##// END OF EJS Templates
Merge pull request #4504 from takluyver/inputtransformer-syntaxerror...
Fernando Perez -
r14990:07072a49 merge
parent child Browse files
Show More
@@ -0,0 +1,6 b''
1 * :class:`IPython.core.inputsplitter.IPythonInputSplitter` no longer has a method
2 ``source_raw_reset()``, but gains :meth:`~IPython.core.inputsplitter.IPythonInputSplitter.raw_reset`
3 instead. Use of ``source_raw_reset`` can be replaced with::
4
5 raw = isp.source_raw
6 transformed = isp.source_reset()
@@ -0,0 +1,4 b''
1 * Input transformers (see :doc:`/config/inputtransforms`) may now raise
2 :exc:`SyntaxError` if they determine that input is invalid. The input
3 transformation machinery in IPython will handle displaying the exception to
4 the user and resetting state.
@@ -1,627 +1,638 b''
1 """Input handling and transformation machinery.
1 """Input handling and transformation machinery.
2
2
3 The first class in this module, :class:`InputSplitter`, is designed to tell when
3 The first class in this module, :class:`InputSplitter`, is designed to tell when
4 input from a line-oriented frontend is complete and should be executed, and when
4 input from a line-oriented frontend is complete and should be executed, and when
5 the user should be prompted for another line of code instead. The name 'input
5 the user should be prompted for another line of code instead. The name 'input
6 splitter' is largely for historical reasons.
6 splitter' is largely for historical reasons.
7
7
8 A companion, :class:`IPythonInputSplitter`, provides the same functionality but
8 A companion, :class:`IPythonInputSplitter`, provides the same functionality but
9 with full support for the extended IPython syntax (magics, system calls, etc).
9 with full support for the extended IPython syntax (magics, system calls, etc).
10 The code to actually do these transformations is in :mod:`IPython.core.inputtransformer`.
10 The code to actually do these transformations is in :mod:`IPython.core.inputtransformer`.
11 :class:`IPythonInputSplitter` feeds the raw code to the transformers in order
11 :class:`IPythonInputSplitter` feeds the raw code to the transformers in order
12 and stores the results.
12 and stores the results.
13
13
14 For more details, see the class docstrings below.
14 For more details, see the class docstrings below.
15
15
16 Authors
16 Authors
17 -------
17 -------
18
18
19 * Fernando Perez
19 * Fernando Perez
20 * Brian Granger
20 * Brian Granger
21 * Thomas Kluyver
21 * Thomas Kluyver
22 """
22 """
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Copyright (C) 2010 The IPython Development Team
24 # Copyright (C) 2010 The IPython Development Team
25 #
25 #
26 # Distributed under the terms of the BSD License. The full license is in
26 # Distributed under the terms of the BSD License. The full license is in
27 # the file COPYING, distributed as part of this software.
27 # the file COPYING, distributed as part of this software.
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Imports
31 # Imports
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # stdlib
33 # stdlib
34 import ast
34 import ast
35 import codeop
35 import codeop
36 import re
36 import re
37 import sys
37 import sys
38
38
39 # IPython modules
39 # IPython modules
40 from IPython.utils.py3compat import cast_unicode
40 from IPython.utils.py3compat import cast_unicode
41 from IPython.core.inputtransformer import (leading_indent,
41 from IPython.core.inputtransformer import (leading_indent,
42 classic_prompt,
42 classic_prompt,
43 ipy_prompt,
43 ipy_prompt,
44 strip_encoding_cookie,
44 strip_encoding_cookie,
45 cellmagic,
45 cellmagic,
46 assemble_logical_lines,
46 assemble_logical_lines,
47 help_end,
47 help_end,
48 escaped_commands,
48 escaped_commands,
49 assign_from_magic,
49 assign_from_magic,
50 assign_from_system,
50 assign_from_system,
51 assemble_python_lines,
51 assemble_python_lines,
52 )
52 )
53
53
54 # These are available in this module for backwards compatibility.
54 # These are available in this module for backwards compatibility.
55 from IPython.core.inputtransformer import (ESC_SHELL, ESC_SH_CAP, ESC_HELP,
55 from IPython.core.inputtransformer import (ESC_SHELL, ESC_SH_CAP, ESC_HELP,
56 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,
56 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,
57 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN, ESC_SEQUENCES)
57 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN, ESC_SEQUENCES)
58
58
59 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
60 # Utilities
60 # Utilities
61 #-----------------------------------------------------------------------------
61 #-----------------------------------------------------------------------------
62
62
63 # FIXME: These are general-purpose utilities that later can be moved to the
63 # FIXME: These are general-purpose utilities that later can be moved to the
64 # general ward. Kept here for now because we're being very strict about test
64 # general ward. Kept here for now because we're being very strict about test
65 # coverage with this code, and this lets us ensure that we keep 100% coverage
65 # coverage with this code, and this lets us ensure that we keep 100% coverage
66 # while developing.
66 # while developing.
67
67
68 # compiled regexps for autoindent management
68 # compiled regexps for autoindent management
69 dedent_re = re.compile('|'.join([
69 dedent_re = re.compile('|'.join([
70 r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
70 r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
71 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
71 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
72 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
72 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
73 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
73 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
74 r'^\s+pass\s*$', # pass (optionally followed by trailing spaces)
74 r'^\s+pass\s*$', # pass (optionally followed by trailing spaces)
75 r'^\s+break\s*$', # break (optionally followed by trailing spaces)
75 r'^\s+break\s*$', # break (optionally followed by trailing spaces)
76 r'^\s+continue\s*$', # continue (optionally followed by trailing spaces)
76 r'^\s+continue\s*$', # continue (optionally followed by trailing spaces)
77 ]))
77 ]))
78 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
78 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
79
79
80 # regexp to match pure comment lines so we don't accidentally insert 'if 1:'
80 # regexp to match pure comment lines so we don't accidentally insert 'if 1:'
81 # before pure comments
81 # before pure comments
82 comment_line_re = re.compile('^\s*\#')
82 comment_line_re = re.compile('^\s*\#')
83
83
84
84
85 def num_ini_spaces(s):
85 def num_ini_spaces(s):
86 """Return the number of initial spaces in a string.
86 """Return the number of initial spaces in a string.
87
87
88 Note that tabs are counted as a single space. For now, we do *not* support
88 Note that tabs are counted as a single space. For now, we do *not* support
89 mixing of tabs and spaces in the user's input.
89 mixing of tabs and spaces in the user's input.
90
90
91 Parameters
91 Parameters
92 ----------
92 ----------
93 s : string
93 s : string
94
94
95 Returns
95 Returns
96 -------
96 -------
97 n : int
97 n : int
98 """
98 """
99
99
100 ini_spaces = ini_spaces_re.match(s)
100 ini_spaces = ini_spaces_re.match(s)
101 if ini_spaces:
101 if ini_spaces:
102 return ini_spaces.end()
102 return ini_spaces.end()
103 else:
103 else:
104 return 0
104 return 0
105
105
106 def last_blank(src):
106 def last_blank(src):
107 """Determine if the input source ends in a blank.
107 """Determine if the input source ends in a blank.
108
108
109 A blank is either a newline or a line consisting of whitespace.
109 A blank is either a newline or a line consisting of whitespace.
110
110
111 Parameters
111 Parameters
112 ----------
112 ----------
113 src : string
113 src : string
114 A single or multiline string.
114 A single or multiline string.
115 """
115 """
116 if not src: return False
116 if not src: return False
117 ll = src.splitlines()[-1]
117 ll = src.splitlines()[-1]
118 return (ll == '') or ll.isspace()
118 return (ll == '') or ll.isspace()
119
119
120
120
121 last_two_blanks_re = re.compile(r'\n\s*\n\s*$', re.MULTILINE)
121 last_two_blanks_re = re.compile(r'\n\s*\n\s*$', re.MULTILINE)
122 last_two_blanks_re2 = re.compile(r'.+\n\s*\n\s+$', re.MULTILINE)
122 last_two_blanks_re2 = re.compile(r'.+\n\s*\n\s+$', re.MULTILINE)
123
123
124 def last_two_blanks(src):
124 def last_two_blanks(src):
125 """Determine if the input source ends in two blanks.
125 """Determine if the input source ends in two blanks.
126
126
127 A blank is either a newline or a line consisting of whitespace.
127 A blank is either a newline or a line consisting of whitespace.
128
128
129 Parameters
129 Parameters
130 ----------
130 ----------
131 src : string
131 src : string
132 A single or multiline string.
132 A single or multiline string.
133 """
133 """
134 if not src: return False
134 if not src: return False
135 # The logic here is tricky: I couldn't get a regexp to work and pass all
135 # The logic here is tricky: I couldn't get a regexp to work and pass all
136 # the tests, so I took a different approach: split the source by lines,
136 # the tests, so I took a different approach: split the source by lines,
137 # grab the last two and prepend '###\n' as a stand-in for whatever was in
137 # grab the last two and prepend '###\n' as a stand-in for whatever was in
138 # the body before the last two lines. Then, with that structure, it's
138 # the body before the last two lines. Then, with that structure, it's
139 # possible to analyze with two regexps. Not the most elegant solution, but
139 # possible to analyze with two regexps. Not the most elegant solution, but
140 # it works. If anyone tries to change this logic, make sure to validate
140 # it works. If anyone tries to change this logic, make sure to validate
141 # the whole test suite first!
141 # the whole test suite first!
142 new_src = '\n'.join(['###\n'] + src.splitlines()[-2:])
142 new_src = '\n'.join(['###\n'] + src.splitlines()[-2:])
143 return (bool(last_two_blanks_re.match(new_src)) or
143 return (bool(last_two_blanks_re.match(new_src)) or
144 bool(last_two_blanks_re2.match(new_src)) )
144 bool(last_two_blanks_re2.match(new_src)) )
145
145
146
146
147 def remove_comments(src):
147 def remove_comments(src):
148 """Remove all comments from input source.
148 """Remove all comments from input source.
149
149
150 Note: comments are NOT recognized inside of strings!
150 Note: comments are NOT recognized inside of strings!
151
151
152 Parameters
152 Parameters
153 ----------
153 ----------
154 src : string
154 src : string
155 A single or multiline input string.
155 A single or multiline input string.
156
156
157 Returns
157 Returns
158 -------
158 -------
159 String with all Python comments removed.
159 String with all Python comments removed.
160 """
160 """
161
161
162 return re.sub('#.*', '', src)
162 return re.sub('#.*', '', src)
163
163
164
164
165 def get_input_encoding():
165 def get_input_encoding():
166 """Return the default standard input encoding.
166 """Return the default standard input encoding.
167
167
168 If sys.stdin has no encoding, 'ascii' is returned."""
168 If sys.stdin has no encoding, 'ascii' is returned."""
169 # There are strange environments for which sys.stdin.encoding is None. We
169 # There are strange environments for which sys.stdin.encoding is None. We
170 # ensure that a valid encoding is returned.
170 # ensure that a valid encoding is returned.
171 encoding = getattr(sys.stdin, 'encoding', None)
171 encoding = getattr(sys.stdin, 'encoding', None)
172 if encoding is None:
172 if encoding is None:
173 encoding = 'ascii'
173 encoding = 'ascii'
174 return encoding
174 return encoding
175
175
176 #-----------------------------------------------------------------------------
176 #-----------------------------------------------------------------------------
177 # Classes and functions for normal Python syntax handling
177 # Classes and functions for normal Python syntax handling
178 #-----------------------------------------------------------------------------
178 #-----------------------------------------------------------------------------
179
179
180 class InputSplitter(object):
180 class InputSplitter(object):
181 r"""An object that can accumulate lines of Python source before execution.
181 r"""An object that can accumulate lines of Python source before execution.
182
182
183 This object is designed to be fed python source line-by-line, using
183 This object is designed to be fed python source line-by-line, using
184 :meth:`push`. It will return on each push whether the currently pushed
184 :meth:`push`. It will return on each push whether the currently pushed
185 code could be executed already. In addition, it provides a method called
185 code could be executed already. In addition, it provides a method called
186 :meth:`push_accepts_more` that can be used to query whether more input
186 :meth:`push_accepts_more` that can be used to query whether more input
187 can be pushed into a single interactive block.
187 can be pushed into a single interactive block.
188
188
189 This is a simple example of how an interactive terminal-based client can use
189 This is a simple example of how an interactive terminal-based client can use
190 this tool::
190 this tool::
191
191
192 isp = InputSplitter()
192 isp = InputSplitter()
193 while isp.push_accepts_more():
193 while isp.push_accepts_more():
194 indent = ' '*isp.indent_spaces
194 indent = ' '*isp.indent_spaces
195 prompt = '>>> ' + indent
195 prompt = '>>> ' + indent
196 line = indent + raw_input(prompt)
196 line = indent + raw_input(prompt)
197 isp.push(line)
197 isp.push(line)
198 print 'Input source was:\n', isp.source_reset(),
198 print 'Input source was:\n', isp.source_reset(),
199 """
199 """
200 # Number of spaces of indentation computed from input that has been pushed
200 # Number of spaces of indentation computed from input that has been pushed
201 # so far. This is the attributes callers should query to get the current
201 # so far. This is the attributes callers should query to get the current
202 # indentation level, in order to provide auto-indent facilities.
202 # indentation level, in order to provide auto-indent facilities.
203 indent_spaces = 0
203 indent_spaces = 0
204 # String, indicating the default input encoding. It is computed by default
204 # String, indicating the default input encoding. It is computed by default
205 # at initialization time via get_input_encoding(), but it can be reset by a
205 # at initialization time via get_input_encoding(), but it can be reset by a
206 # client with specific knowledge of the encoding.
206 # client with specific knowledge of the encoding.
207 encoding = ''
207 encoding = ''
208 # String where the current full source input is stored, properly encoded.
208 # String where the current full source input is stored, properly encoded.
209 # Reading this attribute is the normal way of querying the currently pushed
209 # Reading this attribute is the normal way of querying the currently pushed
210 # source code, that has been properly encoded.
210 # source code, that has been properly encoded.
211 source = ''
211 source = ''
212 # Code object corresponding to the current source. It is automatically
212 # Code object corresponding to the current source. It is automatically
213 # synced to the source, so it can be queried at any time to obtain the code
213 # synced to the source, so it can be queried at any time to obtain the code
214 # object; it will be None if the source doesn't compile to valid Python.
214 # object; it will be None if the source doesn't compile to valid Python.
215 code = None
215 code = None
216
216
217 # Private attributes
217 # Private attributes
218
218
219 # List with lines of input accumulated so far
219 # List with lines of input accumulated so far
220 _buffer = None
220 _buffer = None
221 # Command compiler
221 # Command compiler
222 _compile = None
222 _compile = None
223 # Mark when input has changed indentation all the way back to flush-left
223 # Mark when input has changed indentation all the way back to flush-left
224 _full_dedent = False
224 _full_dedent = False
225 # Boolean indicating whether the current block is complete
225 # Boolean indicating whether the current block is complete
226 _is_complete = None
226 _is_complete = None
227
227
228 def __init__(self):
228 def __init__(self):
229 """Create a new InputSplitter instance.
229 """Create a new InputSplitter instance.
230 """
230 """
231 self._buffer = []
231 self._buffer = []
232 self._compile = codeop.CommandCompiler()
232 self._compile = codeop.CommandCompiler()
233 self.encoding = get_input_encoding()
233 self.encoding = get_input_encoding()
234
234
235 def reset(self):
235 def reset(self):
236 """Reset the input buffer and associated state."""
236 """Reset the input buffer and associated state."""
237 self.indent_spaces = 0
237 self.indent_spaces = 0
238 self._buffer[:] = []
238 self._buffer[:] = []
239 self.source = ''
239 self.source = ''
240 self.code = None
240 self.code = None
241 self._is_complete = False
241 self._is_complete = False
242 self._full_dedent = False
242 self._full_dedent = False
243
243
244 def source_reset(self):
244 def source_reset(self):
245 """Return the input source and perform a full reset.
245 """Return the input source and perform a full reset.
246 """
246 """
247 out = self.source
247 out = self.source
248 self.reset()
248 self.reset()
249 return out
249 return out
250
250
251 def push(self, lines):
251 def push(self, lines):
252 """Push one or more lines of input.
252 """Push one or more lines of input.
253
253
254 This stores the given lines and returns a status code indicating
254 This stores the given lines and returns a status code indicating
255 whether the code forms a complete Python block or not.
255 whether the code forms a complete Python block or not.
256
256
257 Any exceptions generated in compilation are swallowed, but if an
257 Any exceptions generated in compilation are swallowed, but if an
258 exception was produced, the method returns True.
258 exception was produced, the method returns True.
259
259
260 Parameters
260 Parameters
261 ----------
261 ----------
262 lines : string
262 lines : string
263 One or more lines of Python input.
263 One or more lines of Python input.
264
264
265 Returns
265 Returns
266 -------
266 -------
267 is_complete : boolean
267 is_complete : boolean
268 True if the current input source (the result of the current input
268 True if the current input source (the result of the current input
269 plus prior inputs) forms a complete Python execution block. Note that
269 plus prior inputs) forms a complete Python execution block. Note that
270 this value is also stored as a private attribute (``_is_complete``), so it
270 this value is also stored as a private attribute (``_is_complete``), so it
271 can be queried at any time.
271 can be queried at any time.
272 """
272 """
273 self._store(lines)
273 self._store(lines)
274 source = self.source
274 source = self.source
275
275
276 # Before calling _compile(), reset the code object to None so that if an
276 # Before calling _compile(), reset the code object to None so that if an
277 # exception is raised in compilation, we don't mislead by having
277 # exception is raised in compilation, we don't mislead by having
278 # inconsistent code/source attributes.
278 # inconsistent code/source attributes.
279 self.code, self._is_complete = None, None
279 self.code, self._is_complete = None, None
280
280
281 # Honor termination lines properly
281 # Honor termination lines properly
282 if source.endswith('\\\n'):
282 if source.endswith('\\\n'):
283 return False
283 return False
284
284
285 self._update_indent(lines)
285 self._update_indent(lines)
286 try:
286 try:
287 self.code = self._compile(source, symbol="exec")
287 self.code = self._compile(source, symbol="exec")
288 # Invalid syntax can produce any of a number of different errors from
288 # Invalid syntax can produce any of a number of different errors from
289 # inside the compiler, so we have to catch them all. Syntax errors
289 # inside the compiler, so we have to catch them all. Syntax errors
290 # immediately produce a 'ready' block, so the invalid Python can be
290 # immediately produce a 'ready' block, so the invalid Python can be
291 # sent to the kernel for evaluation with possible ipython
291 # sent to the kernel for evaluation with possible ipython
292 # special-syntax conversion.
292 # special-syntax conversion.
293 except (SyntaxError, OverflowError, ValueError, TypeError,
293 except (SyntaxError, OverflowError, ValueError, TypeError,
294 MemoryError):
294 MemoryError):
295 self._is_complete = True
295 self._is_complete = True
296 else:
296 else:
297 # Compilation didn't produce any exceptions (though it may not have
297 # Compilation didn't produce any exceptions (though it may not have
298 # given a complete code object)
298 # given a complete code object)
299 self._is_complete = self.code is not None
299 self._is_complete = self.code is not None
300
300
301 return self._is_complete
301 return self._is_complete
302
302
303 def push_accepts_more(self):
303 def push_accepts_more(self):
304 """Return whether a block of interactive input can accept more input.
304 """Return whether a block of interactive input can accept more input.
305
305
306 This method is meant to be used by line-oriented frontends, who need to
306 This method is meant to be used by line-oriented frontends, who need to
307 guess whether a block is complete or not based solely on prior and
307 guess whether a block is complete or not based solely on prior and
308 current input lines. The InputSplitter considers it has a complete
308 current input lines. The InputSplitter considers it has a complete
309 interactive block and will not accept more input when either:
309 interactive block and will not accept more input when either:
310
310
311 * A SyntaxError is raised
311 * A SyntaxError is raised
312
312
313 * The code is complete and consists of a single line or a single
313 * The code is complete and consists of a single line or a single
314 non-compound statement
314 non-compound statement
315
315
316 * The code is complete and has a blank line at the end
316 * The code is complete and has a blank line at the end
317
317
318 If the current input produces a syntax error, this method immediately
318 If the current input produces a syntax error, this method immediately
319 returns False but does *not* raise the syntax error exception, as
319 returns False but does *not* raise the syntax error exception, as
320 typically clients will want to send invalid syntax to an execution
320 typically clients will want to send invalid syntax to an execution
321 backend which might convert the invalid syntax into valid Python via
321 backend which might convert the invalid syntax into valid Python via
322 one of the dynamic IPython mechanisms.
322 one of the dynamic IPython mechanisms.
323 """
323 """
324
324
325 # With incomplete input, unconditionally accept more
325 # With incomplete input, unconditionally accept more
326 # A syntax error also sets _is_complete to True - see push()
326 # A syntax error also sets _is_complete to True - see push()
327 if not self._is_complete:
327 if not self._is_complete:
328 #print("Not complete") # debug
328 #print("Not complete") # debug
329 return True
329 return True
330
330
331 # The user can make any (complete) input execute by leaving a blank line
331 # The user can make any (complete) input execute by leaving a blank line
332 last_line = self.source.splitlines()[-1]
332 last_line = self.source.splitlines()[-1]
333 if (not last_line) or last_line.isspace():
333 if (not last_line) or last_line.isspace():
334 #print("Blank line") # debug
334 #print("Blank line") # debug
335 return False
335 return False
336
336
337 # If there's just a single line or AST node, and we're flush left, as is
337 # If there's just a single line or AST node, and we're flush left, as is
338 # the case after a simple statement such as 'a=1', we want to execute it
338 # the case after a simple statement such as 'a=1', we want to execute it
339 # straight away.
339 # straight away.
340 if self.indent_spaces==0:
340 if self.indent_spaces==0:
341 if len(self.source.splitlines()) <= 1:
341 if len(self.source.splitlines()) <= 1:
342 return False
342 return False
343
343
344 try:
344 try:
345 code_ast = ast.parse(u''.join(self._buffer))
345 code_ast = ast.parse(u''.join(self._buffer))
346 except Exception:
346 except Exception:
347 #print("Can't parse AST") # debug
347 #print("Can't parse AST") # debug
348 return False
348 return False
349 else:
349 else:
350 if len(code_ast.body) == 1 and \
350 if len(code_ast.body) == 1 and \
351 not hasattr(code_ast.body[0], 'body'):
351 not hasattr(code_ast.body[0], 'body'):
352 #print("Simple statement") # debug
352 #print("Simple statement") # debug
353 return False
353 return False
354
354
355 # General fallback - accept more code
355 # General fallback - accept more code
356 return True
356 return True
357
357
358 #------------------------------------------------------------------------
358 #------------------------------------------------------------------------
359 # Private interface
359 # Private interface
360 #------------------------------------------------------------------------
360 #------------------------------------------------------------------------
361
361
362 def _find_indent(self, line):
362 def _find_indent(self, line):
363 """Compute the new indentation level for a single line.
363 """Compute the new indentation level for a single line.
364
364
365 Parameters
365 Parameters
366 ----------
366 ----------
367 line : str
367 line : str
368 A single new line of non-whitespace, non-comment Python input.
368 A single new line of non-whitespace, non-comment Python input.
369
369
370 Returns
370 Returns
371 -------
371 -------
372 indent_spaces : int
372 indent_spaces : int
373 New value for the indent level (it may be equal to self.indent_spaces
373 New value for the indent level (it may be equal to self.indent_spaces
374 if indentation doesn't change.
374 if indentation doesn't change.
375
375
376 full_dedent : boolean
376 full_dedent : boolean
377 Whether the new line causes a full flush-left dedent.
377 Whether the new line causes a full flush-left dedent.
378 """
378 """
379 indent_spaces = self.indent_spaces
379 indent_spaces = self.indent_spaces
380 full_dedent = self._full_dedent
380 full_dedent = self._full_dedent
381
381
382 inisp = num_ini_spaces(line)
382 inisp = num_ini_spaces(line)
383 if inisp < indent_spaces:
383 if inisp < indent_spaces:
384 indent_spaces = inisp
384 indent_spaces = inisp
385 if indent_spaces <= 0:
385 if indent_spaces <= 0:
386 #print 'Full dedent in text',self.source # dbg
386 #print 'Full dedent in text',self.source # dbg
387 full_dedent = True
387 full_dedent = True
388
388
389 if line.rstrip()[-1] == ':':
389 if line.rstrip()[-1] == ':':
390 indent_spaces += 4
390 indent_spaces += 4
391 elif dedent_re.match(line):
391 elif dedent_re.match(line):
392 indent_spaces -= 4
392 indent_spaces -= 4
393 if indent_spaces <= 0:
393 if indent_spaces <= 0:
394 full_dedent = True
394 full_dedent = True
395
395
396 # Safety
396 # Safety
397 if indent_spaces < 0:
397 if indent_spaces < 0:
398 indent_spaces = 0
398 indent_spaces = 0
399 #print 'safety' # dbg
399 #print 'safety' # dbg
400
400
401 return indent_spaces, full_dedent
401 return indent_spaces, full_dedent
402
402
403 def _update_indent(self, lines):
403 def _update_indent(self, lines):
404 for line in remove_comments(lines).splitlines():
404 for line in remove_comments(lines).splitlines():
405 if line and not line.isspace():
405 if line and not line.isspace():
406 self.indent_spaces, self._full_dedent = self._find_indent(line)
406 self.indent_spaces, self._full_dedent = self._find_indent(line)
407
407
408 def _store(self, lines, buffer=None, store='source'):
408 def _store(self, lines, buffer=None, store='source'):
409 """Store one or more lines of input.
409 """Store one or more lines of input.
410
410
411 If input lines are not newline-terminated, a newline is automatically
411 If input lines are not newline-terminated, a newline is automatically
412 appended."""
412 appended."""
413
413
414 if buffer is None:
414 if buffer is None:
415 buffer = self._buffer
415 buffer = self._buffer
416
416
417 if lines.endswith('\n'):
417 if lines.endswith('\n'):
418 buffer.append(lines)
418 buffer.append(lines)
419 else:
419 else:
420 buffer.append(lines+'\n')
420 buffer.append(lines+'\n')
421 setattr(self, store, self._set_source(buffer))
421 setattr(self, store, self._set_source(buffer))
422
422
423 def _set_source(self, buffer):
423 def _set_source(self, buffer):
424 return u''.join(buffer)
424 return u''.join(buffer)
425
425
426
426
427 class IPythonInputSplitter(InputSplitter):
427 class IPythonInputSplitter(InputSplitter):
428 """An input splitter that recognizes all of IPython's special syntax."""
428 """An input splitter that recognizes all of IPython's special syntax."""
429
429
430 # String with raw, untransformed input.
430 # String with raw, untransformed input.
431 source_raw = ''
431 source_raw = ''
432
432
433 # Flag to track when a transformer has stored input that it hasn't given
433 # Flag to track when a transformer has stored input that it hasn't given
434 # back yet.
434 # back yet.
435 transformer_accumulating = False
435 transformer_accumulating = False
436
436
437 # Flag to track when assemble_python_lines has stored input that it hasn't
437 # Flag to track when assemble_python_lines has stored input that it hasn't
438 # given back yet.
438 # given back yet.
439 within_python_line = False
439 within_python_line = False
440
440
441 # Private attributes
441 # Private attributes
442
442
443 # List with lines of raw input accumulated so far.
443 # List with lines of raw input accumulated so far.
444 _buffer_raw = None
444 _buffer_raw = None
445
445
446 def __init__(self, line_input_checker=True, physical_line_transforms=None,
446 def __init__(self, line_input_checker=True, physical_line_transforms=None,
447 logical_line_transforms=None, python_line_transforms=None):
447 logical_line_transforms=None, python_line_transforms=None):
448 super(IPythonInputSplitter, self).__init__()
448 super(IPythonInputSplitter, self).__init__()
449 self._buffer_raw = []
449 self._buffer_raw = []
450 self._validate = True
450 self._validate = True
451
451
452 if physical_line_transforms is not None:
452 if physical_line_transforms is not None:
453 self.physical_line_transforms = physical_line_transforms
453 self.physical_line_transforms = physical_line_transforms
454 else:
454 else:
455 self.physical_line_transforms = [
455 self.physical_line_transforms = [
456 leading_indent(),
456 leading_indent(),
457 classic_prompt(),
457 classic_prompt(),
458 ipy_prompt(),
458 ipy_prompt(),
459 strip_encoding_cookie(),
459 strip_encoding_cookie(),
460 cellmagic(end_on_blank_line=line_input_checker),
460 cellmagic(end_on_blank_line=line_input_checker),
461 ]
461 ]
462
462
463 self.assemble_logical_lines = assemble_logical_lines()
463 self.assemble_logical_lines = assemble_logical_lines()
464 if logical_line_transforms is not None:
464 if logical_line_transforms is not None:
465 self.logical_line_transforms = logical_line_transforms
465 self.logical_line_transforms = logical_line_transforms
466 else:
466 else:
467 self.logical_line_transforms = [
467 self.logical_line_transforms = [
468 help_end(),
468 help_end(),
469 escaped_commands(),
469 escaped_commands(),
470 assign_from_magic(),
470 assign_from_magic(),
471 assign_from_system(),
471 assign_from_system(),
472 ]
472 ]
473
473
474 self.assemble_python_lines = assemble_python_lines()
474 self.assemble_python_lines = assemble_python_lines()
475 if python_line_transforms is not None:
475 if python_line_transforms is not None:
476 self.python_line_transforms = python_line_transforms
476 self.python_line_transforms = python_line_transforms
477 else:
477 else:
478 # We don't use any of these at present
478 # We don't use any of these at present
479 self.python_line_transforms = []
479 self.python_line_transforms = []
480
480
481 @property
481 @property
482 def transforms(self):
482 def transforms(self):
483 "Quick access to all transformers."
483 "Quick access to all transformers."
484 return self.physical_line_transforms + \
484 return self.physical_line_transforms + \
485 [self.assemble_logical_lines] + self.logical_line_transforms + \
485 [self.assemble_logical_lines] + self.logical_line_transforms + \
486 [self.assemble_python_lines] + self.python_line_transforms
486 [self.assemble_python_lines] + self.python_line_transforms
487
487
488 @property
488 @property
489 def transforms_in_use(self):
489 def transforms_in_use(self):
490 """Transformers, excluding logical line transformers if we're in a
490 """Transformers, excluding logical line transformers if we're in a
491 Python line."""
491 Python line."""
492 t = self.physical_line_transforms[:]
492 t = self.physical_line_transforms[:]
493 if not self.within_python_line:
493 if not self.within_python_line:
494 t += [self.assemble_logical_lines] + self.logical_line_transforms
494 t += [self.assemble_logical_lines] + self.logical_line_transforms
495 return t + [self.assemble_python_lines] + self.python_line_transforms
495 return t + [self.assemble_python_lines] + self.python_line_transforms
496
496
497 def reset(self):
497 def reset(self):
498 """Reset the input buffer and associated state."""
498 """Reset the input buffer and associated state."""
499 super(IPythonInputSplitter, self).reset()
499 super(IPythonInputSplitter, self).reset()
500 self._buffer_raw[:] = []
500 self._buffer_raw[:] = []
501 self.source_raw = ''
501 self.source_raw = ''
502 self.transformer_accumulating = False
502 self.transformer_accumulating = False
503 self.within_python_line = False
503 self.within_python_line = False
504
504 for t in self.transforms:
505 for t in self.transforms:
505 t.reset()
506 try:
507 t.reset()
508 except SyntaxError:
509 # Nothing that calls reset() expects to handle transformer
510 # errors
511 pass
506
512
507 def flush_transformers(self):
513 def flush_transformers(self):
508 def _flush(transform, out):
514 def _flush(transform, out):
509 if out is not None:
515 if out is not None:
510 tmp = transform.push(out)
516 tmp = transform.push(out)
511 return tmp or transform.reset() or None
517 return tmp or transform.reset() or None
512 else:
518 else:
513 return transform.reset() or None
519 return transform.reset() or None
514
520
515 out = None
521 out = None
516 for t in self.transforms_in_use:
522 for t in self.transforms_in_use:
517 out = _flush(t, out)
523 out = _flush(t, out)
518
524
519 if out is not None:
525 if out is not None:
520 self._store(out)
526 self._store(out)
521
527
522 def source_raw_reset(self):
528 def raw_reset(self):
523 """Return input and raw source and perform a full reset.
529 """Return raw input only and perform a full reset.
524 """
530 """
525 self.flush_transformers()
531 out = self.source_raw
526 out = self.source
527 out_r = self.source_raw
528 self.reset()
532 self.reset()
529 return out, out_r
533 return out
530
534
531 def source_reset(self):
535 def source_reset(self):
532 self.flush_transformers()
536 try:
533 return super(IPythonInputSplitter, self).source_reset()
537 self.flush_transformers()
538 return self.source
539 finally:
540 self.reset()
534
541
535 def push_accepts_more(self):
542 def push_accepts_more(self):
536 if self.transformer_accumulating:
543 if self.transformer_accumulating:
537 return True
544 return True
538 else:
545 else:
539 return super(IPythonInputSplitter, self).push_accepts_more()
546 return super(IPythonInputSplitter, self).push_accepts_more()
540
547
541 def transform_cell(self, cell):
548 def transform_cell(self, cell):
542 """Process and translate a cell of input.
549 """Process and translate a cell of input.
543 """
550 """
544 self.reset()
551 self.reset()
545 self.push(cell)
552 try:
546 return self.source_reset()
553 self.push(cell)
554 self.flush_transformers()
555 return self.source
556 finally:
557 self.reset()
547
558
548 def push(self, lines):
559 def push(self, lines):
549 """Push one or more lines of IPython input.
560 """Push one or more lines of IPython input.
550
561
551 This stores the given lines and returns a status code indicating
562 This stores the given lines and returns a status code indicating
552 whether the code forms a complete Python block or not, after processing
563 whether the code forms a complete Python block or not, after processing
553 all input lines for special IPython syntax.
564 all input lines for special IPython syntax.
554
565
555 Any exceptions generated in compilation are swallowed, but if an
566 Any exceptions generated in compilation are swallowed, but if an
556 exception was produced, the method returns True.
567 exception was produced, the method returns True.
557
568
558 Parameters
569 Parameters
559 ----------
570 ----------
560 lines : string
571 lines : string
561 One or more lines of Python input.
572 One or more lines of Python input.
562
573
563 Returns
574 Returns
564 -------
575 -------
565 is_complete : boolean
576 is_complete : boolean
566 True if the current input source (the result of the current input
577 True if the current input source (the result of the current input
567 plus prior inputs) forms a complete Python execution block. Note that
578 plus prior inputs) forms a complete Python execution block. Note that
568 this value is also stored as a private attribute (_is_complete), so it
579 this value is also stored as a private attribute (_is_complete), so it
569 can be queried at any time.
580 can be queried at any time.
570 """
581 """
571
582
572 # We must ensure all input is pure unicode
583 # We must ensure all input is pure unicode
573 lines = cast_unicode(lines, self.encoding)
584 lines = cast_unicode(lines, self.encoding)
574
585
575 # ''.splitlines() --> [], but we need to push the empty line to transformers
586 # ''.splitlines() --> [], but we need to push the empty line to transformers
576 lines_list = lines.splitlines()
587 lines_list = lines.splitlines()
577 if not lines_list:
588 if not lines_list:
578 lines_list = ['']
589 lines_list = ['']
579
590
580 # Store raw source before applying any transformations to it. Note
591 # Store raw source before applying any transformations to it. Note
581 # that this must be done *after* the reset() call that would otherwise
592 # that this must be done *after* the reset() call that would otherwise
582 # flush the buffer.
593 # flush the buffer.
583 self._store(lines, self._buffer_raw, 'source_raw')
594 self._store(lines, self._buffer_raw, 'source_raw')
584
595
585 for line in lines_list:
596 for line in lines_list:
586 out = self.push_line(line)
597 out = self.push_line(line)
587
598
588 return out
599 return out
589
600
590 def push_line(self, line):
601 def push_line(self, line):
591 buf = self._buffer
602 buf = self._buffer
592
603
593 def _accumulating(dbg):
604 def _accumulating(dbg):
594 #print(dbg)
605 #print(dbg)
595 self.transformer_accumulating = True
606 self.transformer_accumulating = True
596 return False
607 return False
597
608
598 for transformer in self.physical_line_transforms:
609 for transformer in self.physical_line_transforms:
599 line = transformer.push(line)
610 line = transformer.push(line)
600 if line is None:
611 if line is None:
601 return _accumulating(transformer)
612 return _accumulating(transformer)
602
613
603 if not self.within_python_line:
614 if not self.within_python_line:
604 line = self.assemble_logical_lines.push(line)
615 line = self.assemble_logical_lines.push(line)
605 if line is None:
616 if line is None:
606 return _accumulating('acc logical line')
617 return _accumulating('acc logical line')
607
618
608 for transformer in self.logical_line_transforms:
619 for transformer in self.logical_line_transforms:
609 line = transformer.push(line)
620 line = transformer.push(line)
610 if line is None:
621 if line is None:
611 return _accumulating(transformer)
622 return _accumulating(transformer)
612
623
613 line = self.assemble_python_lines.push(line)
624 line = self.assemble_python_lines.push(line)
614 if line is None:
625 if line is None:
615 self.within_python_line = True
626 self.within_python_line = True
616 return _accumulating('acc python line')
627 return _accumulating('acc python line')
617 else:
628 else:
618 self.within_python_line = False
629 self.within_python_line = False
619
630
620 for transformer in self.python_line_transforms:
631 for transformer in self.python_line_transforms:
621 line = transformer.push(line)
632 line = transformer.push(line)
622 if line is None:
633 if line is None:
623 return _accumulating(transformer)
634 return _accumulating(transformer)
624
635
625 #print("transformers clear") #debug
636 #print("transformers clear") #debug
626 self.transformer_accumulating = False
637 self.transformer_accumulating = False
627 return super(IPythonInputSplitter, self).push(line)
638 return super(IPythonInputSplitter, self).push(line)
@@ -1,539 +1,542 b''
1 """Input transformer classes to support IPython special syntax.
1 """Input transformer classes to support IPython special syntax.
2
2
3 This includes the machinery to recognise and transform ``%magic`` commands,
3 This includes the machinery to recognise and transform ``%magic`` commands,
4 ``!system`` commands, ``help?`` querying, prompt stripping, and so forth.
4 ``!system`` commands, ``help?`` querying, prompt stripping, and so forth.
5 """
5 """
6 import abc
6 import abc
7 import functools
7 import functools
8 import re
8 import re
9
9
10 from IPython.core.splitinput import LineInfo
10 from IPython.core.splitinput import LineInfo
11 from IPython.utils import tokenize2
11 from IPython.utils import tokenize2
12 from IPython.utils.openpy import cookie_comment_re
12 from IPython.utils.openpy import cookie_comment_re
13 from IPython.utils.py3compat import with_metaclass, PY3
13 from IPython.utils.py3compat import with_metaclass, PY3
14 from IPython.utils.tokenize2 import generate_tokens, untokenize, TokenError
14 from IPython.utils.tokenize2 import generate_tokens, untokenize, TokenError
15
15
16 if PY3:
16 if PY3:
17 from io import StringIO
17 from io import StringIO
18 else:
18 else:
19 from StringIO import StringIO
19 from StringIO import StringIO
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Globals
22 # Globals
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 # The escape sequences that define the syntax transformations IPython will
25 # The escape sequences that define the syntax transformations IPython will
26 # apply to user input. These can NOT be just changed here: many regular
26 # apply to user input. These can NOT be just changed here: many regular
27 # expressions and other parts of the code may use their hardcoded values, and
27 # expressions and other parts of the code may use their hardcoded values, and
28 # for all intents and purposes they constitute the 'IPython syntax', so they
28 # for all intents and purposes they constitute the 'IPython syntax', so they
29 # should be considered fixed.
29 # should be considered fixed.
30
30
31 ESC_SHELL = '!' # Send line to underlying system shell
31 ESC_SHELL = '!' # Send line to underlying system shell
32 ESC_SH_CAP = '!!' # Send line to system shell and capture output
32 ESC_SH_CAP = '!!' # Send line to system shell and capture output
33 ESC_HELP = '?' # Find information about object
33 ESC_HELP = '?' # Find information about object
34 ESC_HELP2 = '??' # Find extra-detailed information about object
34 ESC_HELP2 = '??' # Find extra-detailed information about object
35 ESC_MAGIC = '%' # Call magic function
35 ESC_MAGIC = '%' # Call magic function
36 ESC_MAGIC2 = '%%' # Call cell-magic function
36 ESC_MAGIC2 = '%%' # Call cell-magic function
37 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
37 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
38 ESC_QUOTE2 = ';' # Quote all args as a single string, call
38 ESC_QUOTE2 = ';' # Quote all args as a single string, call
39 ESC_PAREN = '/' # Call first argument with rest of line as arguments
39 ESC_PAREN = '/' # Call first argument with rest of line as arguments
40
40
41 ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
41 ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
42 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
42 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
43 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
43 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
44
44
45
45
46 class InputTransformer(with_metaclass(abc.ABCMeta, object)):
46 class InputTransformer(with_metaclass(abc.ABCMeta, object)):
47 """Abstract base class for line-based input transformers."""
47 """Abstract base class for line-based input transformers."""
48
48
49 @abc.abstractmethod
49 @abc.abstractmethod
50 def push(self, line):
50 def push(self, line):
51 """Send a line of input to the transformer, returning the transformed
51 """Send a line of input to the transformer, returning the transformed
52 input or None if the transformer is waiting for more input.
52 input or None if the transformer is waiting for more input.
53
53
54 Must be overridden by subclasses.
54 Must be overridden by subclasses.
55
56 Implementations may raise ``SyntaxError`` if the input is invalid. No
57 other exceptions may be raised.
55 """
58 """
56 pass
59 pass
57
60
58 @abc.abstractmethod
61 @abc.abstractmethod
59 def reset(self):
62 def reset(self):
60 """Return, transformed any lines that the transformer has accumulated,
63 """Return, transformed any lines that the transformer has accumulated,
61 and reset its internal state.
64 and reset its internal state.
62
65
63 Must be overridden by subclasses.
66 Must be overridden by subclasses.
64 """
67 """
65 pass
68 pass
66
69
67 @classmethod
70 @classmethod
68 def wrap(cls, func):
71 def wrap(cls, func):
69 """Can be used by subclasses as a decorator, to return a factory that
72 """Can be used by subclasses as a decorator, to return a factory that
70 will allow instantiation with the decorated object.
73 will allow instantiation with the decorated object.
71 """
74 """
72 @functools.wraps(func)
75 @functools.wraps(func)
73 def transformer_factory(**kwargs):
76 def transformer_factory(**kwargs):
74 return cls(func, **kwargs)
77 return cls(func, **kwargs)
75
78
76 return transformer_factory
79 return transformer_factory
77
80
78 class StatelessInputTransformer(InputTransformer):
81 class StatelessInputTransformer(InputTransformer):
79 """Wrapper for a stateless input transformer implemented as a function."""
82 """Wrapper for a stateless input transformer implemented as a function."""
80 def __init__(self, func):
83 def __init__(self, func):
81 self.func = func
84 self.func = func
82
85
83 def __repr__(self):
86 def __repr__(self):
84 return "StatelessInputTransformer(func={0!r})".format(self.func)
87 return "StatelessInputTransformer(func={0!r})".format(self.func)
85
88
86 def push(self, line):
89 def push(self, line):
87 """Send a line of input to the transformer, returning the
90 """Send a line of input to the transformer, returning the
88 transformed input."""
91 transformed input."""
89 return self.func(line)
92 return self.func(line)
90
93
91 def reset(self):
94 def reset(self):
92 """No-op - exists for compatibility."""
95 """No-op - exists for compatibility."""
93 pass
96 pass
94
97
95 class CoroutineInputTransformer(InputTransformer):
98 class CoroutineInputTransformer(InputTransformer):
96 """Wrapper for an input transformer implemented as a coroutine."""
99 """Wrapper for an input transformer implemented as a coroutine."""
97 def __init__(self, coro, **kwargs):
100 def __init__(self, coro, **kwargs):
98 # Prime it
101 # Prime it
99 self.coro = coro(**kwargs)
102 self.coro = coro(**kwargs)
100 next(self.coro)
103 next(self.coro)
101
104
102 def __repr__(self):
105 def __repr__(self):
103 return "CoroutineInputTransformer(coro={0!r})".format(self.coro)
106 return "CoroutineInputTransformer(coro={0!r})".format(self.coro)
104
107
105 def push(self, line):
108 def push(self, line):
106 """Send a line of input to the transformer, returning the
109 """Send a line of input to the transformer, returning the
107 transformed input or None if the transformer is waiting for more
110 transformed input or None if the transformer is waiting for more
108 input.
111 input.
109 """
112 """
110 return self.coro.send(line)
113 return self.coro.send(line)
111
114
112 def reset(self):
115 def reset(self):
113 """Return, transformed any lines that the transformer has
116 """Return, transformed any lines that the transformer has
114 accumulated, and reset its internal state.
117 accumulated, and reset its internal state.
115 """
118 """
116 return self.coro.send(None)
119 return self.coro.send(None)
117
120
118 class TokenInputTransformer(InputTransformer):
121 class TokenInputTransformer(InputTransformer):
119 """Wrapper for a token-based input transformer.
122 """Wrapper for a token-based input transformer.
120
123
121 func should accept a list of tokens (5-tuples, see tokenize docs), and
124 func should accept a list of tokens (5-tuples, see tokenize docs), and
122 return an iterable which can be passed to tokenize.untokenize().
125 return an iterable which can be passed to tokenize.untokenize().
123 """
126 """
124 def __init__(self, func):
127 def __init__(self, func):
125 self.func = func
128 self.func = func
126 self.current_line = ""
129 self.current_line = ""
127 self.line_used = False
130 self.line_used = False
128 self.reset_tokenizer()
131 self.reset_tokenizer()
129
132
130 def reset_tokenizer(self):
133 def reset_tokenizer(self):
131 self.tokenizer = generate_tokens(self.get_line)
134 self.tokenizer = generate_tokens(self.get_line)
132
135
133 def get_line(self):
136 def get_line(self):
134 if self.line_used:
137 if self.line_used:
135 raise TokenError
138 raise TokenError
136 self.line_used = True
139 self.line_used = True
137 return self.current_line
140 return self.current_line
138
141
139 def push(self, line):
142 def push(self, line):
140 self.current_line += line + "\n"
143 self.current_line += line + "\n"
141 if self.current_line.isspace():
144 if self.current_line.isspace():
142 return self.reset()
145 return self.reset()
143
146
144 self.line_used = False
147 self.line_used = False
145 tokens = []
148 tokens = []
146 stop_at_NL = False
149 stop_at_NL = False
147 try:
150 try:
148 for intok in self.tokenizer:
151 for intok in self.tokenizer:
149 tokens.append(intok)
152 tokens.append(intok)
150 t = intok[0]
153 t = intok[0]
151 if t == tokenize2.NEWLINE or (stop_at_NL and t == tokenize2.NL):
154 if t == tokenize2.NEWLINE or (stop_at_NL and t == tokenize2.NL):
152 # Stop before we try to pull a line we don't have yet
155 # Stop before we try to pull a line we don't have yet
153 break
156 break
154 elif t == tokenize2.ERRORTOKEN:
157 elif t == tokenize2.ERRORTOKEN:
155 stop_at_NL = True
158 stop_at_NL = True
156 except TokenError:
159 except TokenError:
157 # Multi-line statement - stop and try again with the next line
160 # Multi-line statement - stop and try again with the next line
158 self.reset_tokenizer()
161 self.reset_tokenizer()
159 return None
162 return None
160
163
161 return self.output(tokens)
164 return self.output(tokens)
162
165
163 def output(self, tokens):
166 def output(self, tokens):
164 self.current_line = ""
167 self.current_line = ""
165 self.reset_tokenizer()
168 self.reset_tokenizer()
166 return untokenize(self.func(tokens)).rstrip('\n')
169 return untokenize(self.func(tokens)).rstrip('\n')
167
170
168 def reset(self):
171 def reset(self):
169 l = self.current_line
172 l = self.current_line
170 self.current_line = ""
173 self.current_line = ""
171 self.reset_tokenizer()
174 self.reset_tokenizer()
172 if l:
175 if l:
173 return l.rstrip('\n')
176 return l.rstrip('\n')
174
177
175 class assemble_python_lines(TokenInputTransformer):
178 class assemble_python_lines(TokenInputTransformer):
176 def __init__(self):
179 def __init__(self):
177 super(assemble_python_lines, self).__init__(None)
180 super(assemble_python_lines, self).__init__(None)
178
181
179 def output(self, tokens):
182 def output(self, tokens):
180 return self.reset()
183 return self.reset()
181
184
182 @CoroutineInputTransformer.wrap
185 @CoroutineInputTransformer.wrap
183 def assemble_logical_lines():
186 def assemble_logical_lines():
184 """Join lines following explicit line continuations (\)"""
187 """Join lines following explicit line continuations (\)"""
185 line = ''
188 line = ''
186 while True:
189 while True:
187 line = (yield line)
190 line = (yield line)
188 if not line or line.isspace():
191 if not line or line.isspace():
189 continue
192 continue
190
193
191 parts = []
194 parts = []
192 while line is not None:
195 while line is not None:
193 if line.endswith('\\') and (not has_comment(line)):
196 if line.endswith('\\') and (not has_comment(line)):
194 parts.append(line[:-1])
197 parts.append(line[:-1])
195 line = (yield None) # Get another line
198 line = (yield None) # Get another line
196 else:
199 else:
197 parts.append(line)
200 parts.append(line)
198 break
201 break
199
202
200 # Output
203 # Output
201 line = ''.join(parts)
204 line = ''.join(parts)
202
205
203 # Utilities
206 # Utilities
204 def _make_help_call(target, esc, lspace, next_input=None):
207 def _make_help_call(target, esc, lspace, next_input=None):
205 """Prepares a pinfo(2)/psearch call from a target name and the escape
208 """Prepares a pinfo(2)/psearch call from a target name and the escape
206 (i.e. ? or ??)"""
209 (i.e. ? or ??)"""
207 method = 'pinfo2' if esc == '??' \
210 method = 'pinfo2' if esc == '??' \
208 else 'psearch' if '*' in target \
211 else 'psearch' if '*' in target \
209 else 'pinfo'
212 else 'pinfo'
210 arg = " ".join([method, target])
213 arg = " ".join([method, target])
211 if next_input is None:
214 if next_input is None:
212 return '%sget_ipython().magic(%r)' % (lspace, arg)
215 return '%sget_ipython().magic(%r)' % (lspace, arg)
213 else:
216 else:
214 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
217 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
215 (lspace, next_input, arg)
218 (lspace, next_input, arg)
216
219
217 # These define the transformations for the different escape characters.
220 # These define the transformations for the different escape characters.
218 def _tr_system(line_info):
221 def _tr_system(line_info):
219 "Translate lines escaped with: !"
222 "Translate lines escaped with: !"
220 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
223 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
221 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
224 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
222
225
223 def _tr_system2(line_info):
226 def _tr_system2(line_info):
224 "Translate lines escaped with: !!"
227 "Translate lines escaped with: !!"
225 cmd = line_info.line.lstrip()[2:]
228 cmd = line_info.line.lstrip()[2:]
226 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
229 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
227
230
228 def _tr_help(line_info):
231 def _tr_help(line_info):
229 "Translate lines escaped with: ?/??"
232 "Translate lines escaped with: ?/??"
230 # A naked help line should just fire the intro help screen
233 # A naked help line should just fire the intro help screen
231 if not line_info.line[1:]:
234 if not line_info.line[1:]:
232 return 'get_ipython().show_usage()'
235 return 'get_ipython().show_usage()'
233
236
234 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
237 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
235
238
236 def _tr_magic(line_info):
239 def _tr_magic(line_info):
237 "Translate lines escaped with: %"
240 "Translate lines escaped with: %"
238 tpl = '%sget_ipython().magic(%r)'
241 tpl = '%sget_ipython().magic(%r)'
239 if line_info.line.startswith(ESC_MAGIC2):
242 if line_info.line.startswith(ESC_MAGIC2):
240 return line_info.line
243 return line_info.line
241 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
244 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
242 return tpl % (line_info.pre, cmd)
245 return tpl % (line_info.pre, cmd)
243
246
244 def _tr_quote(line_info):
247 def _tr_quote(line_info):
245 "Translate lines escaped with: ,"
248 "Translate lines escaped with: ,"
246 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
249 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
247 '", "'.join(line_info.the_rest.split()) )
250 '", "'.join(line_info.the_rest.split()) )
248
251
249 def _tr_quote2(line_info):
252 def _tr_quote2(line_info):
250 "Translate lines escaped with: ;"
253 "Translate lines escaped with: ;"
251 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
254 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
252 line_info.the_rest)
255 line_info.the_rest)
253
256
254 def _tr_paren(line_info):
257 def _tr_paren(line_info):
255 "Translate lines escaped with: /"
258 "Translate lines escaped with: /"
256 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
259 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
257 ", ".join(line_info.the_rest.split()))
260 ", ".join(line_info.the_rest.split()))
258
261
259 tr = { ESC_SHELL : _tr_system,
262 tr = { ESC_SHELL : _tr_system,
260 ESC_SH_CAP : _tr_system2,
263 ESC_SH_CAP : _tr_system2,
261 ESC_HELP : _tr_help,
264 ESC_HELP : _tr_help,
262 ESC_HELP2 : _tr_help,
265 ESC_HELP2 : _tr_help,
263 ESC_MAGIC : _tr_magic,
266 ESC_MAGIC : _tr_magic,
264 ESC_QUOTE : _tr_quote,
267 ESC_QUOTE : _tr_quote,
265 ESC_QUOTE2 : _tr_quote2,
268 ESC_QUOTE2 : _tr_quote2,
266 ESC_PAREN : _tr_paren }
269 ESC_PAREN : _tr_paren }
267
270
268 @StatelessInputTransformer.wrap
271 @StatelessInputTransformer.wrap
269 def escaped_commands(line):
272 def escaped_commands(line):
270 """Transform escaped commands - %magic, !system, ?help + various autocalls.
273 """Transform escaped commands - %magic, !system, ?help + various autocalls.
271 """
274 """
272 if not line or line.isspace():
275 if not line or line.isspace():
273 return line
276 return line
274 lineinf = LineInfo(line)
277 lineinf = LineInfo(line)
275 if lineinf.esc not in tr:
278 if lineinf.esc not in tr:
276 return line
279 return line
277
280
278 return tr[lineinf.esc](lineinf)
281 return tr[lineinf.esc](lineinf)
279
282
280 _initial_space_re = re.compile(r'\s*')
283 _initial_space_re = re.compile(r'\s*')
281
284
282 _help_end_re = re.compile(r"""(%{0,2}
285 _help_end_re = re.compile(r"""(%{0,2}
283 [a-zA-Z_*][\w*]* # Variable name
286 [a-zA-Z_*][\w*]* # Variable name
284 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
287 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
285 )
288 )
286 (\?\??)$ # ? or ??
289 (\?\??)$ # ? or ??
287 """,
290 """,
288 re.VERBOSE)
291 re.VERBOSE)
289
292
290 # Extra pseudotokens for multiline strings and data structures
293 # Extra pseudotokens for multiline strings and data structures
291 _MULTILINE_STRING = object()
294 _MULTILINE_STRING = object()
292 _MULTILINE_STRUCTURE = object()
295 _MULTILINE_STRUCTURE = object()
293
296
294 def _line_tokens(line):
297 def _line_tokens(line):
295 """Helper for has_comment and ends_in_comment_or_string."""
298 """Helper for has_comment and ends_in_comment_or_string."""
296 readline = StringIO(line).readline
299 readline = StringIO(line).readline
297 toktypes = set()
300 toktypes = set()
298 try:
301 try:
299 for t in generate_tokens(readline):
302 for t in generate_tokens(readline):
300 toktypes.add(t[0])
303 toktypes.add(t[0])
301 except TokenError as e:
304 except TokenError as e:
302 # There are only two cases where a TokenError is raised.
305 # There are only two cases where a TokenError is raised.
303 if 'multi-line string' in e.args[0]:
306 if 'multi-line string' in e.args[0]:
304 toktypes.add(_MULTILINE_STRING)
307 toktypes.add(_MULTILINE_STRING)
305 else:
308 else:
306 toktypes.add(_MULTILINE_STRUCTURE)
309 toktypes.add(_MULTILINE_STRUCTURE)
307 return toktypes
310 return toktypes
308
311
309 def has_comment(src):
312 def has_comment(src):
310 """Indicate whether an input line has (i.e. ends in, or is) a comment.
313 """Indicate whether an input line has (i.e. ends in, or is) a comment.
311
314
312 This uses tokenize, so it can distinguish comments from # inside strings.
315 This uses tokenize, so it can distinguish comments from # inside strings.
313
316
314 Parameters
317 Parameters
315 ----------
318 ----------
316 src : string
319 src : string
317 A single line input string.
320 A single line input string.
318
321
319 Returns
322 Returns
320 -------
323 -------
321 comment : bool
324 comment : bool
322 True if source has a comment.
325 True if source has a comment.
323 """
326 """
324 return (tokenize2.COMMENT in _line_tokens(src))
327 return (tokenize2.COMMENT in _line_tokens(src))
325
328
326 def ends_in_comment_or_string(src):
329 def ends_in_comment_or_string(src):
327 """Indicates whether or not an input line ends in a comment or within
330 """Indicates whether or not an input line ends in a comment or within
328 a multiline string.
331 a multiline string.
329
332
330 Parameters
333 Parameters
331 ----------
334 ----------
332 src : string
335 src : string
333 A single line input string.
336 A single line input string.
334
337
335 Returns
338 Returns
336 -------
339 -------
337 comment : bool
340 comment : bool
338 True if source ends in a comment or multiline string.
341 True if source ends in a comment or multiline string.
339 """
342 """
340 toktypes = _line_tokens(src)
343 toktypes = _line_tokens(src)
341 return (tokenize2.COMMENT in toktypes) or (_MULTILINE_STRING in toktypes)
344 return (tokenize2.COMMENT in toktypes) or (_MULTILINE_STRING in toktypes)
342
345
343
346
344 @StatelessInputTransformer.wrap
347 @StatelessInputTransformer.wrap
345 def help_end(line):
348 def help_end(line):
346 """Translate lines with ?/?? at the end"""
349 """Translate lines with ?/?? at the end"""
347 m = _help_end_re.search(line)
350 m = _help_end_re.search(line)
348 if m is None or ends_in_comment_or_string(line):
351 if m is None or ends_in_comment_or_string(line):
349 return line
352 return line
350 target = m.group(1)
353 target = m.group(1)
351 esc = m.group(3)
354 esc = m.group(3)
352 lspace = _initial_space_re.match(line).group(0)
355 lspace = _initial_space_re.match(line).group(0)
353
356
354 # If we're mid-command, put it back on the next prompt for the user.
357 # If we're mid-command, put it back on the next prompt for the user.
355 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
358 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
356
359
357 return _make_help_call(target, esc, lspace, next_input)
360 return _make_help_call(target, esc, lspace, next_input)
358
361
359
362
360 @CoroutineInputTransformer.wrap
363 @CoroutineInputTransformer.wrap
361 def cellmagic(end_on_blank_line=False):
364 def cellmagic(end_on_blank_line=False):
362 """Captures & transforms cell magics.
365 """Captures & transforms cell magics.
363
366
364 After a cell magic is started, this stores up any lines it gets until it is
367 After a cell magic is started, this stores up any lines it gets until it is
365 reset (sent None).
368 reset (sent None).
366 """
369 """
367 tpl = 'get_ipython().run_cell_magic(%r, %r, %r)'
370 tpl = 'get_ipython().run_cell_magic(%r, %r, %r)'
368 cellmagic_help_re = re.compile('%%\w+\?')
371 cellmagic_help_re = re.compile('%%\w+\?')
369 line = ''
372 line = ''
370 while True:
373 while True:
371 line = (yield line)
374 line = (yield line)
372 # consume leading empty lines
375 # consume leading empty lines
373 while not line:
376 while not line:
374 line = (yield line)
377 line = (yield line)
375
378
376 if not line.startswith(ESC_MAGIC2):
379 if not line.startswith(ESC_MAGIC2):
377 # This isn't a cell magic, idle waiting for reset then start over
380 # This isn't a cell magic, idle waiting for reset then start over
378 while line is not None:
381 while line is not None:
379 line = (yield line)
382 line = (yield line)
380 continue
383 continue
381
384
382 if cellmagic_help_re.match(line):
385 if cellmagic_help_re.match(line):
383 # This case will be handled by help_end
386 # This case will be handled by help_end
384 continue
387 continue
385
388
386 first = line
389 first = line
387 body = []
390 body = []
388 line = (yield None)
391 line = (yield None)
389 while (line is not None) and \
392 while (line is not None) and \
390 ((line.strip() != '') or not end_on_blank_line):
393 ((line.strip() != '') or not end_on_blank_line):
391 body.append(line)
394 body.append(line)
392 line = (yield None)
395 line = (yield None)
393
396
394 # Output
397 # Output
395 magic_name, _, first = first.partition(' ')
398 magic_name, _, first = first.partition(' ')
396 magic_name = magic_name.lstrip(ESC_MAGIC2)
399 magic_name = magic_name.lstrip(ESC_MAGIC2)
397 line = tpl % (magic_name, first, u'\n'.join(body))
400 line = tpl % (magic_name, first, u'\n'.join(body))
398
401
399
402
400 def _strip_prompts(prompt_re, initial_re=None):
403 def _strip_prompts(prompt_re, initial_re=None):
401 """Remove matching input prompts from a block of input.
404 """Remove matching input prompts from a block of input.
402
405
403 Parameters
406 Parameters
404 ----------
407 ----------
405 prompt_re : regular expression
408 prompt_re : regular expression
406 A regular expression matching any input prompt (including continuation)
409 A regular expression matching any input prompt (including continuation)
407 initial_re : regular expression, optional
410 initial_re : regular expression, optional
408 A regular expression matching only the initial prompt, but not continuation.
411 A regular expression matching only the initial prompt, but not continuation.
409 If no initial expression is given, prompt_re will be used everywhere.
412 If no initial expression is given, prompt_re will be used everywhere.
410 Used mainly for plain Python prompts, where the continuation prompt
413 Used mainly for plain Python prompts, where the continuation prompt
411 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
414 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
412
415
413 If initial_re and prompt_re differ,
416 If initial_re and prompt_re differ,
414 only initial_re will be tested against the first line.
417 only initial_re will be tested against the first line.
415 If any prompt is found on the first two lines,
418 If any prompt is found on the first two lines,
416 prompts will be stripped from the rest of the block.
419 prompts will be stripped from the rest of the block.
417 """
420 """
418 if initial_re is None:
421 if initial_re is None:
419 initial_re = prompt_re
422 initial_re = prompt_re
420 line = ''
423 line = ''
421 while True:
424 while True:
422 line = (yield line)
425 line = (yield line)
423
426
424 # First line of cell
427 # First line of cell
425 if line is None:
428 if line is None:
426 continue
429 continue
427 out, n1 = initial_re.subn('', line, count=1)
430 out, n1 = initial_re.subn('', line, count=1)
428 line = (yield out)
431 line = (yield out)
429
432
430 if line is None:
433 if line is None:
431 continue
434 continue
432 # check for any prompt on the second line of the cell,
435 # check for any prompt on the second line of the cell,
433 # because people often copy from just after the first prompt,
436 # because people often copy from just after the first prompt,
434 # so we might not see it in the first line.
437 # so we might not see it in the first line.
435 out, n2 = prompt_re.subn('', line, count=1)
438 out, n2 = prompt_re.subn('', line, count=1)
436 line = (yield out)
439 line = (yield out)
437
440
438 if n1 or n2:
441 if n1 or n2:
439 # Found a prompt in the first two lines - check for it in
442 # Found a prompt in the first two lines - check for it in
440 # the rest of the cell as well.
443 # the rest of the cell as well.
441 while line is not None:
444 while line is not None:
442 line = (yield prompt_re.sub('', line, count=1))
445 line = (yield prompt_re.sub('', line, count=1))
443
446
444 else:
447 else:
445 # Prompts not in input - wait for reset
448 # Prompts not in input - wait for reset
446 while line is not None:
449 while line is not None:
447 line = (yield line)
450 line = (yield line)
448
451
449 @CoroutineInputTransformer.wrap
452 @CoroutineInputTransformer.wrap
450 def classic_prompt():
453 def classic_prompt():
451 """Strip the >>>/... prompts of the Python interactive shell."""
454 """Strip the >>>/... prompts of the Python interactive shell."""
452 # FIXME: non-capturing version (?:...) usable?
455 # FIXME: non-capturing version (?:...) usable?
453 prompt_re = re.compile(r'^(>>> ?|\.\.\. ?)')
456 prompt_re = re.compile(r'^(>>> ?|\.\.\. ?)')
454 initial_re = re.compile(r'^(>>> ?)')
457 initial_re = re.compile(r'^(>>> ?)')
455 return _strip_prompts(prompt_re, initial_re)
458 return _strip_prompts(prompt_re, initial_re)
456
459
457 @CoroutineInputTransformer.wrap
460 @CoroutineInputTransformer.wrap
458 def ipy_prompt():
461 def ipy_prompt():
459 """Strip IPython's In [1]:/...: prompts."""
462 """Strip IPython's In [1]:/...: prompts."""
460 # FIXME: non-capturing version (?:...) usable?
463 # FIXME: non-capturing version (?:...) usable?
461 prompt_re = re.compile(r'^(In \[\d+\]: |\ {3,}\.{3,}: )')
464 prompt_re = re.compile(r'^(In \[\d+\]: |\ {3,}\.{3,}: )')
462 return _strip_prompts(prompt_re)
465 return _strip_prompts(prompt_re)
463
466
464
467
465 @CoroutineInputTransformer.wrap
468 @CoroutineInputTransformer.wrap
466 def leading_indent():
469 def leading_indent():
467 """Remove leading indentation.
470 """Remove leading indentation.
468
471
469 If the first line starts with a spaces or tabs, the same whitespace will be
472 If the first line starts with a spaces or tabs, the same whitespace will be
470 removed from each following line until it is reset.
473 removed from each following line until it is reset.
471 """
474 """
472 space_re = re.compile(r'^[ \t]+')
475 space_re = re.compile(r'^[ \t]+')
473 line = ''
476 line = ''
474 while True:
477 while True:
475 line = (yield line)
478 line = (yield line)
476
479
477 if line is None:
480 if line is None:
478 continue
481 continue
479
482
480 m = space_re.match(line)
483 m = space_re.match(line)
481 if m:
484 if m:
482 space = m.group(0)
485 space = m.group(0)
483 while line is not None:
486 while line is not None:
484 if line.startswith(space):
487 if line.startswith(space):
485 line = line[len(space):]
488 line = line[len(space):]
486 line = (yield line)
489 line = (yield line)
487 else:
490 else:
488 # No leading spaces - wait for reset
491 # No leading spaces - wait for reset
489 while line is not None:
492 while line is not None:
490 line = (yield line)
493 line = (yield line)
491
494
492
495
493 @CoroutineInputTransformer.wrap
496 @CoroutineInputTransformer.wrap
494 def strip_encoding_cookie():
497 def strip_encoding_cookie():
495 """Remove encoding comment if found in first two lines
498 """Remove encoding comment if found in first two lines
496
499
497 If the first or second line has the `# coding: utf-8` comment,
500 If the first or second line has the `# coding: utf-8` comment,
498 it will be removed.
501 it will be removed.
499 """
502 """
500 line = ''
503 line = ''
501 while True:
504 while True:
502 line = (yield line)
505 line = (yield line)
503 # check comment on first two lines
506 # check comment on first two lines
504 for i in range(2):
507 for i in range(2):
505 if line is None:
508 if line is None:
506 break
509 break
507 if cookie_comment_re.match(line):
510 if cookie_comment_re.match(line):
508 line = (yield "")
511 line = (yield "")
509 else:
512 else:
510 line = (yield line)
513 line = (yield line)
511
514
512 # no-op on the rest of the cell
515 # no-op on the rest of the cell
513 while line is not None:
516 while line is not None:
514 line = (yield line)
517 line = (yield line)
515
518
516
519
517 assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
520 assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
518 r'\s*=\s*!\s*(?P<cmd>.*)')
521 r'\s*=\s*!\s*(?P<cmd>.*)')
519 assign_system_template = '%s = get_ipython().getoutput(%r)'
522 assign_system_template = '%s = get_ipython().getoutput(%r)'
520 @StatelessInputTransformer.wrap
523 @StatelessInputTransformer.wrap
521 def assign_from_system(line):
524 def assign_from_system(line):
522 """Transform assignment from system commands (e.g. files = !ls)"""
525 """Transform assignment from system commands (e.g. files = !ls)"""
523 m = assign_system_re.match(line)
526 m = assign_system_re.match(line)
524 if m is None:
527 if m is None:
525 return line
528 return line
526
529
527 return assign_system_template % m.group('lhs', 'cmd')
530 return assign_system_template % m.group('lhs', 'cmd')
528
531
529 assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
532 assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
530 r'\s*=\s*%\s*(?P<cmd>.*)')
533 r'\s*=\s*%\s*(?P<cmd>.*)')
531 assign_magic_template = '%s = get_ipython().magic(%r)'
534 assign_magic_template = '%s = get_ipython().magic(%r)'
532 @StatelessInputTransformer.wrap
535 @StatelessInputTransformer.wrap
533 def assign_from_magic(line):
536 def assign_from_magic(line):
534 """Transform assignment from magic commands (e.g. a = %who_ls)"""
537 """Transform assignment from magic commands (e.g. a = %who_ls)"""
535 m = assign_magic_re.match(line)
538 m = assign_magic_re.match(line)
536 if m is None:
539 if m is None:
537 return line
540 return line
538
541
539 return assign_magic_template % m.group('lhs', 'cmd')
542 return assign_magic_template % m.group('lhs', 'cmd')
@@ -1,3199 +1,3213 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-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 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 absolute_import
17 from __future__ import absolute_import
18 from __future__ import print_function
18 from __future__ import print_function
19
19
20 import __future__
20 import __future__
21 import abc
21 import abc
22 import ast
22 import ast
23 import atexit
23 import atexit
24 import functools
24 import functools
25 import os
25 import os
26 import re
26 import re
27 import runpy
27 import runpy
28 import sys
28 import sys
29 import tempfile
29 import tempfile
30 import types
30 import types
31 import subprocess
31 import subprocess
32 from io import open as io_open
32 from io import open as io_open
33
33
34 from IPython.config.configurable import SingletonConfigurable
34 from IPython.config.configurable import SingletonConfigurable
35 from IPython.core import debugger, oinspect
35 from IPython.core import debugger, oinspect
36 from IPython.core import magic
36 from IPython.core import magic
37 from IPython.core import page
37 from IPython.core import page
38 from IPython.core import prefilter
38 from IPython.core import prefilter
39 from IPython.core import shadowns
39 from IPython.core import shadowns
40 from IPython.core import ultratb
40 from IPython.core import ultratb
41 from IPython.core.alias import AliasManager, AliasError
41 from IPython.core.alias import AliasManager, AliasError
42 from IPython.core.autocall import ExitAutocall
42 from IPython.core.autocall import ExitAutocall
43 from IPython.core.builtin_trap import BuiltinTrap
43 from IPython.core.builtin_trap import BuiltinTrap
44 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
44 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
45 from IPython.core.display_trap import DisplayTrap
45 from IPython.core.display_trap import DisplayTrap
46 from IPython.core.displayhook import DisplayHook
46 from IPython.core.displayhook import DisplayHook
47 from IPython.core.displaypub import DisplayPublisher
47 from IPython.core.displaypub import DisplayPublisher
48 from IPython.core.error import UsageError
48 from IPython.core.error import UsageError
49 from IPython.core.extensions import ExtensionManager
49 from IPython.core.extensions import ExtensionManager
50 from IPython.core.formatters import DisplayFormatter
50 from IPython.core.formatters import DisplayFormatter
51 from IPython.core.history import HistoryManager
51 from IPython.core.history import HistoryManager
52 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
52 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
53 from IPython.core.logger import Logger
53 from IPython.core.logger import Logger
54 from IPython.core.macro import Macro
54 from IPython.core.macro import Macro
55 from IPython.core.payload import PayloadManager
55 from IPython.core.payload import PayloadManager
56 from IPython.core.prefilter import PrefilterManager
56 from IPython.core.prefilter import PrefilterManager
57 from IPython.core.profiledir import ProfileDir
57 from IPython.core.profiledir import ProfileDir
58 from IPython.core.prompts import PromptManager
58 from IPython.core.prompts import PromptManager
59 from IPython.lib.latextools import LaTeXTool
59 from IPython.lib.latextools import LaTeXTool
60 from IPython.testing.skipdoctest import skip_doctest
60 from IPython.testing.skipdoctest import skip_doctest
61 from IPython.utils import PyColorize
61 from IPython.utils import PyColorize
62 from IPython.utils import io
62 from IPython.utils import io
63 from IPython.utils import py3compat
63 from IPython.utils import py3compat
64 from IPython.utils import openpy
64 from IPython.utils import openpy
65 from IPython.utils.decorators import undoc
65 from IPython.utils.decorators import undoc
66 from IPython.utils.io import ask_yes_no
66 from IPython.utils.io import ask_yes_no
67 from IPython.utils.ipstruct import Struct
67 from IPython.utils.ipstruct import Struct
68 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
68 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
69 from IPython.utils.pickleshare import PickleShareDB
69 from IPython.utils.pickleshare import PickleShareDB
70 from IPython.utils.process import system, getoutput
70 from IPython.utils.process import system, getoutput
71 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
71 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
72 with_metaclass, iteritems)
72 with_metaclass, iteritems)
73 from IPython.utils.strdispatch import StrDispatch
73 from IPython.utils.strdispatch import StrDispatch
74 from IPython.utils.syspathcontext import prepended_to_syspath
74 from IPython.utils.syspathcontext import prepended_to_syspath
75 from IPython.utils.text import (format_screen, LSString, SList,
75 from IPython.utils.text import (format_screen, LSString, SList,
76 DollarFormatter)
76 DollarFormatter)
77 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
77 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
78 List, Unicode, Instance, Type)
78 List, Unicode, Instance, Type)
79 from IPython.utils.warn import warn, error
79 from IPython.utils.warn import warn, error
80 import IPython.core.hooks
80 import IPython.core.hooks
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Globals
83 # Globals
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85
85
86 # compiled regexps for autoindent management
86 # compiled regexps for autoindent management
87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
88
88
89 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
90 # Utilities
90 # Utilities
91 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
92
92
93 @undoc
93 @undoc
94 def softspace(file, newvalue):
94 def softspace(file, newvalue):
95 """Copied from code.py, to remove the dependency"""
95 """Copied from code.py, to remove the dependency"""
96
96
97 oldvalue = 0
97 oldvalue = 0
98 try:
98 try:
99 oldvalue = file.softspace
99 oldvalue = file.softspace
100 except AttributeError:
100 except AttributeError:
101 pass
101 pass
102 try:
102 try:
103 file.softspace = newvalue
103 file.softspace = newvalue
104 except (AttributeError, TypeError):
104 except (AttributeError, TypeError):
105 # "attribute-less object" or "read-only attributes"
105 # "attribute-less object" or "read-only attributes"
106 pass
106 pass
107 return oldvalue
107 return oldvalue
108
108
109 @undoc
109 @undoc
110 def no_op(*a, **kw): pass
110 def no_op(*a, **kw): pass
111
111
112 @undoc
112 @undoc
113 class NoOpContext(object):
113 class NoOpContext(object):
114 def __enter__(self): pass
114 def __enter__(self): pass
115 def __exit__(self, type, value, traceback): pass
115 def __exit__(self, type, value, traceback): pass
116 no_op_context = NoOpContext()
116 no_op_context = NoOpContext()
117
117
118 class SpaceInInput(Exception): pass
118 class SpaceInInput(Exception): pass
119
119
120 @undoc
120 @undoc
121 class Bunch: pass
121 class Bunch: pass
122
122
123
123
124 def get_default_colors():
124 def get_default_colors():
125 if sys.platform=='darwin':
125 if sys.platform=='darwin':
126 return "LightBG"
126 return "LightBG"
127 elif os.name=='nt':
127 elif os.name=='nt':
128 return 'Linux'
128 return 'Linux'
129 else:
129 else:
130 return 'Linux'
130 return 'Linux'
131
131
132
132
133 class SeparateUnicode(Unicode):
133 class SeparateUnicode(Unicode):
134 r"""A Unicode subclass to validate separate_in, separate_out, etc.
134 r"""A Unicode subclass to validate separate_in, separate_out, etc.
135
135
136 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
136 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
137 """
137 """
138
138
139 def validate(self, obj, value):
139 def validate(self, obj, value):
140 if value == '0': value = ''
140 if value == '0': value = ''
141 value = value.replace('\\n','\n')
141 value = value.replace('\\n','\n')
142 return super(SeparateUnicode, self).validate(obj, value)
142 return super(SeparateUnicode, self).validate(obj, value)
143
143
144
144
145 class ReadlineNoRecord(object):
145 class ReadlineNoRecord(object):
146 """Context manager to execute some code, then reload readline history
146 """Context manager to execute some code, then reload readline history
147 so that interactive input to the code doesn't appear when pressing up."""
147 so that interactive input to the code doesn't appear when pressing up."""
148 def __init__(self, shell):
148 def __init__(self, shell):
149 self.shell = shell
149 self.shell = shell
150 self._nested_level = 0
150 self._nested_level = 0
151
151
152 def __enter__(self):
152 def __enter__(self):
153 if self._nested_level == 0:
153 if self._nested_level == 0:
154 try:
154 try:
155 self.orig_length = self.current_length()
155 self.orig_length = self.current_length()
156 self.readline_tail = self.get_readline_tail()
156 self.readline_tail = self.get_readline_tail()
157 except (AttributeError, IndexError): # Can fail with pyreadline
157 except (AttributeError, IndexError): # Can fail with pyreadline
158 self.orig_length, self.readline_tail = 999999, []
158 self.orig_length, self.readline_tail = 999999, []
159 self._nested_level += 1
159 self._nested_level += 1
160
160
161 def __exit__(self, type, value, traceback):
161 def __exit__(self, type, value, traceback):
162 self._nested_level -= 1
162 self._nested_level -= 1
163 if self._nested_level == 0:
163 if self._nested_level == 0:
164 # Try clipping the end if it's got longer
164 # Try clipping the end if it's got longer
165 try:
165 try:
166 e = self.current_length() - self.orig_length
166 e = self.current_length() - self.orig_length
167 if e > 0:
167 if e > 0:
168 for _ in range(e):
168 for _ in range(e):
169 self.shell.readline.remove_history_item(self.orig_length)
169 self.shell.readline.remove_history_item(self.orig_length)
170
170
171 # If it still doesn't match, just reload readline history.
171 # If it still doesn't match, just reload readline history.
172 if self.current_length() != self.orig_length \
172 if self.current_length() != self.orig_length \
173 or self.get_readline_tail() != self.readline_tail:
173 or self.get_readline_tail() != self.readline_tail:
174 self.shell.refill_readline_hist()
174 self.shell.refill_readline_hist()
175 except (AttributeError, IndexError):
175 except (AttributeError, IndexError):
176 pass
176 pass
177 # Returning False will cause exceptions to propagate
177 # Returning False will cause exceptions to propagate
178 return False
178 return False
179
179
180 def current_length(self):
180 def current_length(self):
181 return self.shell.readline.get_current_history_length()
181 return self.shell.readline.get_current_history_length()
182
182
183 def get_readline_tail(self, n=10):
183 def get_readline_tail(self, n=10):
184 """Get the last n items in readline history."""
184 """Get the last n items in readline history."""
185 end = self.shell.readline.get_current_history_length() + 1
185 end = self.shell.readline.get_current_history_length() + 1
186 start = max(end-n, 1)
186 start = max(end-n, 1)
187 ghi = self.shell.readline.get_history_item
187 ghi = self.shell.readline.get_history_item
188 return [ghi(x) for x in range(start, end)]
188 return [ghi(x) for x in range(start, end)]
189
189
190
190
191 @undoc
191 @undoc
192 class DummyMod(object):
192 class DummyMod(object):
193 """A dummy module used for IPython's interactive module when
193 """A dummy module used for IPython's interactive module when
194 a namespace must be assigned to the module's __dict__."""
194 a namespace must be assigned to the module's __dict__."""
195 pass
195 pass
196
196
197 #-----------------------------------------------------------------------------
197 #-----------------------------------------------------------------------------
198 # Main IPython class
198 # Main IPython class
199 #-----------------------------------------------------------------------------
199 #-----------------------------------------------------------------------------
200
200
201 class InteractiveShell(SingletonConfigurable):
201 class InteractiveShell(SingletonConfigurable):
202 """An enhanced, interactive shell for Python."""
202 """An enhanced, interactive shell for Python."""
203
203
204 _instance = None
204 _instance = None
205
205
206 ast_transformers = List([], config=True, help=
206 ast_transformers = List([], config=True, help=
207 """
207 """
208 A list of ast.NodeTransformer subclass instances, which will be applied
208 A list of ast.NodeTransformer subclass instances, which will be applied
209 to user input before code is run.
209 to user input before code is run.
210 """
210 """
211 )
211 )
212
212
213 autocall = Enum((0,1,2), default_value=0, config=True, help=
213 autocall = Enum((0,1,2), default_value=0, config=True, help=
214 """
214 """
215 Make IPython automatically call any callable object even if you didn't
215 Make IPython automatically call any callable object even if you didn't
216 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
216 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
217 automatically. The value can be '0' to disable the feature, '1' for
217 automatically. The value can be '0' to disable the feature, '1' for
218 'smart' autocall, where it is not applied if there are no more
218 'smart' autocall, where it is not applied if there are no more
219 arguments on the line, and '2' for 'full' autocall, where all callable
219 arguments on the line, and '2' for 'full' autocall, where all callable
220 objects are automatically called (even if no arguments are present).
220 objects are automatically called (even if no arguments are present).
221 """
221 """
222 )
222 )
223 # TODO: remove all autoindent logic and put into frontends.
223 # TODO: remove all autoindent logic and put into frontends.
224 # We can't do this yet because even runlines uses the autoindent.
224 # We can't do this yet because even runlines uses the autoindent.
225 autoindent = CBool(True, config=True, help=
225 autoindent = CBool(True, config=True, help=
226 """
226 """
227 Autoindent IPython code entered interactively.
227 Autoindent IPython code entered interactively.
228 """
228 """
229 )
229 )
230 automagic = CBool(True, config=True, help=
230 automagic = CBool(True, config=True, help=
231 """
231 """
232 Enable magic commands to be called without the leading %.
232 Enable magic commands to be called without the leading %.
233 """
233 """
234 )
234 )
235 cache_size = Integer(1000, config=True, help=
235 cache_size = Integer(1000, config=True, help=
236 """
236 """
237 Set the size of the output cache. The default is 1000, you can
237 Set the size of the output cache. The default is 1000, you can
238 change it permanently in your config file. Setting it to 0 completely
238 change it permanently in your config file. Setting it to 0 completely
239 disables the caching system, and the minimum value accepted is 20 (if
239 disables the caching system, and the minimum value accepted is 20 (if
240 you provide a value less than 20, it is reset to 0 and a warning is
240 you provide a value less than 20, it is reset to 0 and a warning is
241 issued). This limit is defined because otherwise you'll spend more
241 issued). This limit is defined because otherwise you'll spend more
242 time re-flushing a too small cache than working
242 time re-flushing a too small cache than working
243 """
243 """
244 )
244 )
245 color_info = CBool(True, config=True, help=
245 color_info = CBool(True, config=True, help=
246 """
246 """
247 Use colors for displaying information about objects. Because this
247 Use colors for displaying information about objects. Because this
248 information is passed through a pager (like 'less'), and some pagers
248 information is passed through a pager (like 'less'), and some pagers
249 get confused with color codes, this capability can be turned off.
249 get confused with color codes, this capability can be turned off.
250 """
250 """
251 )
251 )
252 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
252 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
253 default_value=get_default_colors(), config=True,
253 default_value=get_default_colors(), config=True,
254 help="Set the color scheme (NoColor, Linux, or LightBG)."
254 help="Set the color scheme (NoColor, Linux, or LightBG)."
255 )
255 )
256 colors_force = CBool(False, help=
256 colors_force = CBool(False, help=
257 """
257 """
258 Force use of ANSI color codes, regardless of OS and readline
258 Force use of ANSI color codes, regardless of OS and readline
259 availability.
259 availability.
260 """
260 """
261 # FIXME: This is essentially a hack to allow ZMQShell to show colors
261 # FIXME: This is essentially a hack to allow ZMQShell to show colors
262 # without readline on Win32. When the ZMQ formatting system is
262 # without readline on Win32. When the ZMQ formatting system is
263 # refactored, this should be removed.
263 # refactored, this should be removed.
264 )
264 )
265 debug = CBool(False, config=True)
265 debug = CBool(False, config=True)
266 deep_reload = CBool(False, config=True, help=
266 deep_reload = CBool(False, config=True, help=
267 """
267 """
268 Enable deep (recursive) reloading by default. IPython can use the
268 Enable deep (recursive) reloading by default. IPython can use the
269 deep_reload module which reloads changes in modules recursively (it
269 deep_reload module which reloads changes in modules recursively (it
270 replaces the reload() function, so you don't need to change anything to
270 replaces the reload() function, so you don't need to change anything to
271 use it). deep_reload() forces a full reload of modules whose code may
271 use it). deep_reload() forces a full reload of modules whose code may
272 have changed, which the default reload() function does not. When
272 have changed, which the default reload() function does not. When
273 deep_reload is off, IPython will use the normal reload(), but
273 deep_reload is off, IPython will use the normal reload(), but
274 deep_reload will still be available as dreload().
274 deep_reload will still be available as dreload().
275 """
275 """
276 )
276 )
277 disable_failing_post_execute = CBool(False, config=True,
277 disable_failing_post_execute = CBool(False, config=True,
278 help="Don't call post-execute functions that have failed in the past."
278 help="Don't call post-execute functions that have failed in the past."
279 )
279 )
280 display_formatter = Instance(DisplayFormatter)
280 display_formatter = Instance(DisplayFormatter)
281 displayhook_class = Type(DisplayHook)
281 displayhook_class = Type(DisplayHook)
282 display_pub_class = Type(DisplayPublisher)
282 display_pub_class = Type(DisplayPublisher)
283 data_pub_class = None
283 data_pub_class = None
284
284
285 exit_now = CBool(False)
285 exit_now = CBool(False)
286 exiter = Instance(ExitAutocall)
286 exiter = Instance(ExitAutocall)
287 def _exiter_default(self):
287 def _exiter_default(self):
288 return ExitAutocall(self)
288 return ExitAutocall(self)
289 # Monotonically increasing execution counter
289 # Monotonically increasing execution counter
290 execution_count = Integer(1)
290 execution_count = Integer(1)
291 filename = Unicode("<ipython console>")
291 filename = Unicode("<ipython console>")
292 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
292 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
293
293
294 # Input splitter, to transform input line by line and detect when a block
294 # Input splitter, to transform input line by line and detect when a block
295 # is ready to be executed.
295 # is ready to be executed.
296 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
296 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
297 (), {'line_input_checker': True})
297 (), {'line_input_checker': True})
298
298
299 # This InputSplitter instance is used to transform completed cells before
299 # This InputSplitter instance is used to transform completed cells before
300 # running them. It allows cell magics to contain blank lines.
300 # running them. It allows cell magics to contain blank lines.
301 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
301 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
302 (), {'line_input_checker': False})
302 (), {'line_input_checker': False})
303
303
304 logstart = CBool(False, config=True, help=
304 logstart = CBool(False, config=True, help=
305 """
305 """
306 Start logging to the default log file.
306 Start logging to the default log file.
307 """
307 """
308 )
308 )
309 logfile = Unicode('', config=True, help=
309 logfile = Unicode('', config=True, help=
310 """
310 """
311 The name of the logfile to use.
311 The name of the logfile to use.
312 """
312 """
313 )
313 )
314 logappend = Unicode('', config=True, help=
314 logappend = Unicode('', config=True, help=
315 """
315 """
316 Start logging to the given file in append mode.
316 Start logging to the given file in append mode.
317 """
317 """
318 )
318 )
319 object_info_string_level = Enum((0,1,2), default_value=0,
319 object_info_string_level = Enum((0,1,2), default_value=0,
320 config=True)
320 config=True)
321 pdb = CBool(False, config=True, help=
321 pdb = CBool(False, config=True, help=
322 """
322 """
323 Automatically call the pdb debugger after every exception.
323 Automatically call the pdb debugger after every exception.
324 """
324 """
325 )
325 )
326 multiline_history = CBool(sys.platform != 'win32', config=True,
326 multiline_history = CBool(sys.platform != 'win32', config=True,
327 help="Save multi-line entries as one entry in readline history"
327 help="Save multi-line entries as one entry in readline history"
328 )
328 )
329
329
330 # deprecated prompt traits:
330 # deprecated prompt traits:
331
331
332 prompt_in1 = Unicode('In [\\#]: ', config=True,
332 prompt_in1 = Unicode('In [\\#]: ', config=True,
333 help="Deprecated, use PromptManager.in_template")
333 help="Deprecated, use PromptManager.in_template")
334 prompt_in2 = Unicode(' .\\D.: ', config=True,
334 prompt_in2 = Unicode(' .\\D.: ', config=True,
335 help="Deprecated, use PromptManager.in2_template")
335 help="Deprecated, use PromptManager.in2_template")
336 prompt_out = Unicode('Out[\\#]: ', config=True,
336 prompt_out = Unicode('Out[\\#]: ', config=True,
337 help="Deprecated, use PromptManager.out_template")
337 help="Deprecated, use PromptManager.out_template")
338 prompts_pad_left = CBool(True, config=True,
338 prompts_pad_left = CBool(True, config=True,
339 help="Deprecated, use PromptManager.justify")
339 help="Deprecated, use PromptManager.justify")
340
340
341 def _prompt_trait_changed(self, name, old, new):
341 def _prompt_trait_changed(self, name, old, new):
342 table = {
342 table = {
343 'prompt_in1' : 'in_template',
343 'prompt_in1' : 'in_template',
344 'prompt_in2' : 'in2_template',
344 'prompt_in2' : 'in2_template',
345 'prompt_out' : 'out_template',
345 'prompt_out' : 'out_template',
346 'prompts_pad_left' : 'justify',
346 'prompts_pad_left' : 'justify',
347 }
347 }
348 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
348 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
349 name=name, newname=table[name])
349 name=name, newname=table[name])
350 )
350 )
351 # protect against weird cases where self.config may not exist:
351 # protect against weird cases where self.config may not exist:
352 if self.config is not None:
352 if self.config is not None:
353 # propagate to corresponding PromptManager trait
353 # propagate to corresponding PromptManager trait
354 setattr(self.config.PromptManager, table[name], new)
354 setattr(self.config.PromptManager, table[name], new)
355
355
356 _prompt_in1_changed = _prompt_trait_changed
356 _prompt_in1_changed = _prompt_trait_changed
357 _prompt_in2_changed = _prompt_trait_changed
357 _prompt_in2_changed = _prompt_trait_changed
358 _prompt_out_changed = _prompt_trait_changed
358 _prompt_out_changed = _prompt_trait_changed
359 _prompt_pad_left_changed = _prompt_trait_changed
359 _prompt_pad_left_changed = _prompt_trait_changed
360
360
361 show_rewritten_input = CBool(True, config=True,
361 show_rewritten_input = CBool(True, config=True,
362 help="Show rewritten input, e.g. for autocall."
362 help="Show rewritten input, e.g. for autocall."
363 )
363 )
364
364
365 quiet = CBool(False, config=True)
365 quiet = CBool(False, config=True)
366
366
367 history_length = Integer(10000, config=True)
367 history_length = Integer(10000, config=True)
368
368
369 # The readline stuff will eventually be moved to the terminal subclass
369 # The readline stuff will eventually be moved to the terminal subclass
370 # but for now, we can't do that as readline is welded in everywhere.
370 # but for now, we can't do that as readline is welded in everywhere.
371 readline_use = CBool(True, config=True)
371 readline_use = CBool(True, config=True)
372 readline_remove_delims = Unicode('-/~', config=True)
372 readline_remove_delims = Unicode('-/~', config=True)
373 readline_delims = Unicode() # set by init_readline()
373 readline_delims = Unicode() # set by init_readline()
374 # don't use \M- bindings by default, because they
374 # don't use \M- bindings by default, because they
375 # conflict with 8-bit encodings. See gh-58,gh-88
375 # conflict with 8-bit encodings. See gh-58,gh-88
376 readline_parse_and_bind = List([
376 readline_parse_and_bind = List([
377 'tab: complete',
377 'tab: complete',
378 '"\C-l": clear-screen',
378 '"\C-l": clear-screen',
379 'set show-all-if-ambiguous on',
379 'set show-all-if-ambiguous on',
380 '"\C-o": tab-insert',
380 '"\C-o": tab-insert',
381 '"\C-r": reverse-search-history',
381 '"\C-r": reverse-search-history',
382 '"\C-s": forward-search-history',
382 '"\C-s": forward-search-history',
383 '"\C-p": history-search-backward',
383 '"\C-p": history-search-backward',
384 '"\C-n": history-search-forward',
384 '"\C-n": history-search-forward',
385 '"\e[A": history-search-backward',
385 '"\e[A": history-search-backward',
386 '"\e[B": history-search-forward',
386 '"\e[B": history-search-forward',
387 '"\C-k": kill-line',
387 '"\C-k": kill-line',
388 '"\C-u": unix-line-discard',
388 '"\C-u": unix-line-discard',
389 ], allow_none=False, config=True)
389 ], allow_none=False, config=True)
390
390
391 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
391 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
392 default_value='last_expr', config=True,
392 default_value='last_expr', config=True,
393 help="""
393 help="""
394 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
394 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
395 run interactively (displaying output from expressions).""")
395 run interactively (displaying output from expressions).""")
396
396
397 # TODO: this part of prompt management should be moved to the frontends.
397 # TODO: this part of prompt management should be moved to the frontends.
398 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
398 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
399 separate_in = SeparateUnicode('\n', config=True)
399 separate_in = SeparateUnicode('\n', config=True)
400 separate_out = SeparateUnicode('', config=True)
400 separate_out = SeparateUnicode('', config=True)
401 separate_out2 = SeparateUnicode('', config=True)
401 separate_out2 = SeparateUnicode('', config=True)
402 wildcards_case_sensitive = CBool(True, config=True)
402 wildcards_case_sensitive = CBool(True, config=True)
403 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
403 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
404 default_value='Context', config=True)
404 default_value='Context', config=True)
405
405
406 # Subcomponents of InteractiveShell
406 # Subcomponents of InteractiveShell
407 alias_manager = Instance('IPython.core.alias.AliasManager')
407 alias_manager = Instance('IPython.core.alias.AliasManager')
408 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
408 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
409 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
409 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
410 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
410 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
411 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
411 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
412 payload_manager = Instance('IPython.core.payload.PayloadManager')
412 payload_manager = Instance('IPython.core.payload.PayloadManager')
413 history_manager = Instance('IPython.core.history.HistoryManager')
413 history_manager = Instance('IPython.core.history.HistoryManager')
414 magics_manager = Instance('IPython.core.magic.MagicsManager')
414 magics_manager = Instance('IPython.core.magic.MagicsManager')
415
415
416 profile_dir = Instance('IPython.core.application.ProfileDir')
416 profile_dir = Instance('IPython.core.application.ProfileDir')
417 @property
417 @property
418 def profile(self):
418 def profile(self):
419 if self.profile_dir is not None:
419 if self.profile_dir is not None:
420 name = os.path.basename(self.profile_dir.location)
420 name = os.path.basename(self.profile_dir.location)
421 return name.replace('profile_','')
421 return name.replace('profile_','')
422
422
423
423
424 # Private interface
424 # Private interface
425 _post_execute = Instance(dict)
425 _post_execute = Instance(dict)
426
426
427 # Tracks any GUI loop loaded for pylab
427 # Tracks any GUI loop loaded for pylab
428 pylab_gui_select = None
428 pylab_gui_select = None
429
429
430 def __init__(self, ipython_dir=None, profile_dir=None,
430 def __init__(self, ipython_dir=None, profile_dir=None,
431 user_module=None, user_ns=None,
431 user_module=None, user_ns=None,
432 custom_exceptions=((), None), **kwargs):
432 custom_exceptions=((), None), **kwargs):
433
433
434 # This is where traits with a config_key argument are updated
434 # This is where traits with a config_key argument are updated
435 # from the values on config.
435 # from the values on config.
436 super(InteractiveShell, self).__init__(**kwargs)
436 super(InteractiveShell, self).__init__(**kwargs)
437 self.configurables = [self]
437 self.configurables = [self]
438
438
439 # These are relatively independent and stateless
439 # These are relatively independent and stateless
440 self.init_ipython_dir(ipython_dir)
440 self.init_ipython_dir(ipython_dir)
441 self.init_profile_dir(profile_dir)
441 self.init_profile_dir(profile_dir)
442 self.init_instance_attrs()
442 self.init_instance_attrs()
443 self.init_environment()
443 self.init_environment()
444
444
445 # Check if we're in a virtualenv, and set up sys.path.
445 # Check if we're in a virtualenv, and set up sys.path.
446 self.init_virtualenv()
446 self.init_virtualenv()
447
447
448 # Create namespaces (user_ns, user_global_ns, etc.)
448 # Create namespaces (user_ns, user_global_ns, etc.)
449 self.init_create_namespaces(user_module, user_ns)
449 self.init_create_namespaces(user_module, user_ns)
450 # This has to be done after init_create_namespaces because it uses
450 # This has to be done after init_create_namespaces because it uses
451 # something in self.user_ns, but before init_sys_modules, which
451 # something in self.user_ns, but before init_sys_modules, which
452 # is the first thing to modify sys.
452 # is the first thing to modify sys.
453 # TODO: When we override sys.stdout and sys.stderr before this class
453 # TODO: When we override sys.stdout and sys.stderr before this class
454 # is created, we are saving the overridden ones here. Not sure if this
454 # is created, we are saving the overridden ones here. Not sure if this
455 # is what we want to do.
455 # is what we want to do.
456 self.save_sys_module_state()
456 self.save_sys_module_state()
457 self.init_sys_modules()
457 self.init_sys_modules()
458
458
459 # While we're trying to have each part of the code directly access what
459 # While we're trying to have each part of the code directly access what
460 # it needs without keeping redundant references to objects, we have too
460 # it needs without keeping redundant references to objects, we have too
461 # much legacy code that expects ip.db to exist.
461 # much legacy code that expects ip.db to exist.
462 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
462 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
463
463
464 self.init_history()
464 self.init_history()
465 self.init_encoding()
465 self.init_encoding()
466 self.init_prefilter()
466 self.init_prefilter()
467
467
468 self.init_syntax_highlighting()
468 self.init_syntax_highlighting()
469 self.init_hooks()
469 self.init_hooks()
470 self.init_pushd_popd_magic()
470 self.init_pushd_popd_magic()
471 # self.init_traceback_handlers use to be here, but we moved it below
471 # self.init_traceback_handlers use to be here, but we moved it below
472 # because it and init_io have to come after init_readline.
472 # because it and init_io have to come after init_readline.
473 self.init_user_ns()
473 self.init_user_ns()
474 self.init_logger()
474 self.init_logger()
475 self.init_builtins()
475 self.init_builtins()
476
476
477 # The following was in post_config_initialization
477 # The following was in post_config_initialization
478 self.init_inspector()
478 self.init_inspector()
479 # init_readline() must come before init_io(), because init_io uses
479 # init_readline() must come before init_io(), because init_io uses
480 # readline related things.
480 # readline related things.
481 self.init_readline()
481 self.init_readline()
482 # We save this here in case user code replaces raw_input, but it needs
482 # We save this here in case user code replaces raw_input, but it needs
483 # to be after init_readline(), because PyPy's readline works by replacing
483 # to be after init_readline(), because PyPy's readline works by replacing
484 # raw_input.
484 # raw_input.
485 if py3compat.PY3:
485 if py3compat.PY3:
486 self.raw_input_original = input
486 self.raw_input_original = input
487 else:
487 else:
488 self.raw_input_original = raw_input
488 self.raw_input_original = raw_input
489 # init_completer must come after init_readline, because it needs to
489 # init_completer must come after init_readline, because it needs to
490 # know whether readline is present or not system-wide to configure the
490 # know whether readline is present or not system-wide to configure the
491 # completers, since the completion machinery can now operate
491 # completers, since the completion machinery can now operate
492 # independently of readline (e.g. over the network)
492 # independently of readline (e.g. over the network)
493 self.init_completer()
493 self.init_completer()
494 # TODO: init_io() needs to happen before init_traceback handlers
494 # TODO: init_io() needs to happen before init_traceback handlers
495 # because the traceback handlers hardcode the stdout/stderr streams.
495 # because the traceback handlers hardcode the stdout/stderr streams.
496 # This logic in in debugger.Pdb and should eventually be changed.
496 # This logic in in debugger.Pdb and should eventually be changed.
497 self.init_io()
497 self.init_io()
498 self.init_traceback_handlers(custom_exceptions)
498 self.init_traceback_handlers(custom_exceptions)
499 self.init_prompts()
499 self.init_prompts()
500 self.init_display_formatter()
500 self.init_display_formatter()
501 self.init_display_pub()
501 self.init_display_pub()
502 self.init_data_pub()
502 self.init_data_pub()
503 self.init_displayhook()
503 self.init_displayhook()
504 self.init_latextool()
504 self.init_latextool()
505 self.init_magics()
505 self.init_magics()
506 self.init_alias()
506 self.init_alias()
507 self.init_logstart()
507 self.init_logstart()
508 self.init_pdb()
508 self.init_pdb()
509 self.init_extension_manager()
509 self.init_extension_manager()
510 self.init_payload()
510 self.init_payload()
511 self.init_comms()
511 self.init_comms()
512 self.hooks.late_startup_hook()
512 self.hooks.late_startup_hook()
513 atexit.register(self.atexit_operations)
513 atexit.register(self.atexit_operations)
514
514
515 def get_ipython(self):
515 def get_ipython(self):
516 """Return the currently running IPython instance."""
516 """Return the currently running IPython instance."""
517 return self
517 return self
518
518
519 #-------------------------------------------------------------------------
519 #-------------------------------------------------------------------------
520 # Trait changed handlers
520 # Trait changed handlers
521 #-------------------------------------------------------------------------
521 #-------------------------------------------------------------------------
522
522
523 def _ipython_dir_changed(self, name, new):
523 def _ipython_dir_changed(self, name, new):
524 if not os.path.isdir(new):
524 if not os.path.isdir(new):
525 os.makedirs(new, mode = 0o777)
525 os.makedirs(new, mode = 0o777)
526
526
527 def set_autoindent(self,value=None):
527 def set_autoindent(self,value=None):
528 """Set the autoindent flag, checking for readline support.
528 """Set the autoindent flag, checking for readline support.
529
529
530 If called with no arguments, it acts as a toggle."""
530 If called with no arguments, it acts as a toggle."""
531
531
532 if value != 0 and not self.has_readline:
532 if value != 0 and not self.has_readline:
533 if os.name == 'posix':
533 if os.name == 'posix':
534 warn("The auto-indent feature requires the readline library")
534 warn("The auto-indent feature requires the readline library")
535 self.autoindent = 0
535 self.autoindent = 0
536 return
536 return
537 if value is None:
537 if value is None:
538 self.autoindent = not self.autoindent
538 self.autoindent = not self.autoindent
539 else:
539 else:
540 self.autoindent = value
540 self.autoindent = value
541
541
542 #-------------------------------------------------------------------------
542 #-------------------------------------------------------------------------
543 # init_* methods called by __init__
543 # init_* methods called by __init__
544 #-------------------------------------------------------------------------
544 #-------------------------------------------------------------------------
545
545
546 def init_ipython_dir(self, ipython_dir):
546 def init_ipython_dir(self, ipython_dir):
547 if ipython_dir is not None:
547 if ipython_dir is not None:
548 self.ipython_dir = ipython_dir
548 self.ipython_dir = ipython_dir
549 return
549 return
550
550
551 self.ipython_dir = get_ipython_dir()
551 self.ipython_dir = get_ipython_dir()
552
552
553 def init_profile_dir(self, profile_dir):
553 def init_profile_dir(self, profile_dir):
554 if profile_dir is not None:
554 if profile_dir is not None:
555 self.profile_dir = profile_dir
555 self.profile_dir = profile_dir
556 return
556 return
557 self.profile_dir =\
557 self.profile_dir =\
558 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
558 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
559
559
560 def init_instance_attrs(self):
560 def init_instance_attrs(self):
561 self.more = False
561 self.more = False
562
562
563 # command compiler
563 # command compiler
564 self.compile = CachingCompiler()
564 self.compile = CachingCompiler()
565
565
566 # Make an empty namespace, which extension writers can rely on both
566 # Make an empty namespace, which extension writers can rely on both
567 # existing and NEVER being used by ipython itself. This gives them a
567 # existing and NEVER being used by ipython itself. This gives them a
568 # convenient location for storing additional information and state
568 # convenient location for storing additional information and state
569 # their extensions may require, without fear of collisions with other
569 # their extensions may require, without fear of collisions with other
570 # ipython names that may develop later.
570 # ipython names that may develop later.
571 self.meta = Struct()
571 self.meta = Struct()
572
572
573 # Temporary files used for various purposes. Deleted at exit.
573 # Temporary files used for various purposes. Deleted at exit.
574 self.tempfiles = []
574 self.tempfiles = []
575 self.tempdirs = []
575 self.tempdirs = []
576
576
577 # Keep track of readline usage (later set by init_readline)
577 # Keep track of readline usage (later set by init_readline)
578 self.has_readline = False
578 self.has_readline = False
579
579
580 # keep track of where we started running (mainly for crash post-mortem)
580 # keep track of where we started running (mainly for crash post-mortem)
581 # This is not being used anywhere currently.
581 # This is not being used anywhere currently.
582 self.starting_dir = py3compat.getcwd()
582 self.starting_dir = py3compat.getcwd()
583
583
584 # Indentation management
584 # Indentation management
585 self.indent_current_nsp = 0
585 self.indent_current_nsp = 0
586
586
587 # Dict to track post-execution functions that have been registered
587 # Dict to track post-execution functions that have been registered
588 self._post_execute = {}
588 self._post_execute = {}
589
589
590 def init_environment(self):
590 def init_environment(self):
591 """Any changes we need to make to the user's environment."""
591 """Any changes we need to make to the user's environment."""
592 pass
592 pass
593
593
594 def init_encoding(self):
594 def init_encoding(self):
595 # Get system encoding at startup time. Certain terminals (like Emacs
595 # Get system encoding at startup time. Certain terminals (like Emacs
596 # under Win32 have it set to None, and we need to have a known valid
596 # under Win32 have it set to None, and we need to have a known valid
597 # encoding to use in the raw_input() method
597 # encoding to use in the raw_input() method
598 try:
598 try:
599 self.stdin_encoding = sys.stdin.encoding or 'ascii'
599 self.stdin_encoding = sys.stdin.encoding or 'ascii'
600 except AttributeError:
600 except AttributeError:
601 self.stdin_encoding = 'ascii'
601 self.stdin_encoding = 'ascii'
602
602
603 def init_syntax_highlighting(self):
603 def init_syntax_highlighting(self):
604 # Python source parser/formatter for syntax highlighting
604 # Python source parser/formatter for syntax highlighting
605 pyformat = PyColorize.Parser().format
605 pyformat = PyColorize.Parser().format
606 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
606 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
607
607
608 def init_pushd_popd_magic(self):
608 def init_pushd_popd_magic(self):
609 # for pushd/popd management
609 # for pushd/popd management
610 self.home_dir = get_home_dir()
610 self.home_dir = get_home_dir()
611
611
612 self.dir_stack = []
612 self.dir_stack = []
613
613
614 def init_logger(self):
614 def init_logger(self):
615 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
615 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
616 logmode='rotate')
616 logmode='rotate')
617
617
618 def init_logstart(self):
618 def init_logstart(self):
619 """Initialize logging in case it was requested at the command line.
619 """Initialize logging in case it was requested at the command line.
620 """
620 """
621 if self.logappend:
621 if self.logappend:
622 self.magic('logstart %s append' % self.logappend)
622 self.magic('logstart %s append' % self.logappend)
623 elif self.logfile:
623 elif self.logfile:
624 self.magic('logstart %s' % self.logfile)
624 self.magic('logstart %s' % self.logfile)
625 elif self.logstart:
625 elif self.logstart:
626 self.magic('logstart')
626 self.magic('logstart')
627
627
628 def init_builtins(self):
628 def init_builtins(self):
629 # A single, static flag that we set to True. Its presence indicates
629 # A single, static flag that we set to True. Its presence indicates
630 # that an IPython shell has been created, and we make no attempts at
630 # that an IPython shell has been created, and we make no attempts at
631 # removing on exit or representing the existence of more than one
631 # removing on exit or representing the existence of more than one
632 # IPython at a time.
632 # IPython at a time.
633 builtin_mod.__dict__['__IPYTHON__'] = True
633 builtin_mod.__dict__['__IPYTHON__'] = True
634
634
635 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
635 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
636 # manage on enter/exit, but with all our shells it's virtually
636 # manage on enter/exit, but with all our shells it's virtually
637 # impossible to get all the cases right. We're leaving the name in for
637 # impossible to get all the cases right. We're leaving the name in for
638 # those who adapted their codes to check for this flag, but will
638 # those who adapted their codes to check for this flag, but will
639 # eventually remove it after a few more releases.
639 # eventually remove it after a few more releases.
640 builtin_mod.__dict__['__IPYTHON__active'] = \
640 builtin_mod.__dict__['__IPYTHON__active'] = \
641 'Deprecated, check for __IPYTHON__'
641 'Deprecated, check for __IPYTHON__'
642
642
643 self.builtin_trap = BuiltinTrap(shell=self)
643 self.builtin_trap = BuiltinTrap(shell=self)
644
644
645 def init_inspector(self):
645 def init_inspector(self):
646 # Object inspector
646 # Object inspector
647 self.inspector = oinspect.Inspector(oinspect.InspectColors,
647 self.inspector = oinspect.Inspector(oinspect.InspectColors,
648 PyColorize.ANSICodeColors,
648 PyColorize.ANSICodeColors,
649 'NoColor',
649 'NoColor',
650 self.object_info_string_level)
650 self.object_info_string_level)
651
651
652 def init_io(self):
652 def init_io(self):
653 # This will just use sys.stdout and sys.stderr. If you want to
653 # This will just use sys.stdout and sys.stderr. If you want to
654 # override sys.stdout and sys.stderr themselves, you need to do that
654 # override sys.stdout and sys.stderr themselves, you need to do that
655 # *before* instantiating this class, because io holds onto
655 # *before* instantiating this class, because io holds onto
656 # references to the underlying streams.
656 # references to the underlying streams.
657 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
657 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
658 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
658 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
659 else:
659 else:
660 io.stdout = io.IOStream(sys.stdout)
660 io.stdout = io.IOStream(sys.stdout)
661 io.stderr = io.IOStream(sys.stderr)
661 io.stderr = io.IOStream(sys.stderr)
662
662
663 def init_prompts(self):
663 def init_prompts(self):
664 self.prompt_manager = PromptManager(shell=self, parent=self)
664 self.prompt_manager = PromptManager(shell=self, parent=self)
665 self.configurables.append(self.prompt_manager)
665 self.configurables.append(self.prompt_manager)
666 # Set system prompts, so that scripts can decide if they are running
666 # Set system prompts, so that scripts can decide if they are running
667 # interactively.
667 # interactively.
668 sys.ps1 = 'In : '
668 sys.ps1 = 'In : '
669 sys.ps2 = '...: '
669 sys.ps2 = '...: '
670 sys.ps3 = 'Out: '
670 sys.ps3 = 'Out: '
671
671
672 def init_display_formatter(self):
672 def init_display_formatter(self):
673 self.display_formatter = DisplayFormatter(parent=self)
673 self.display_formatter = DisplayFormatter(parent=self)
674 self.configurables.append(self.display_formatter)
674 self.configurables.append(self.display_formatter)
675
675
676 def init_display_pub(self):
676 def init_display_pub(self):
677 self.display_pub = self.display_pub_class(parent=self)
677 self.display_pub = self.display_pub_class(parent=self)
678 self.configurables.append(self.display_pub)
678 self.configurables.append(self.display_pub)
679
679
680 def init_data_pub(self):
680 def init_data_pub(self):
681 if not self.data_pub_class:
681 if not self.data_pub_class:
682 self.data_pub = None
682 self.data_pub = None
683 return
683 return
684 self.data_pub = self.data_pub_class(parent=self)
684 self.data_pub = self.data_pub_class(parent=self)
685 self.configurables.append(self.data_pub)
685 self.configurables.append(self.data_pub)
686
686
687 def init_displayhook(self):
687 def init_displayhook(self):
688 # Initialize displayhook, set in/out prompts and printing system
688 # Initialize displayhook, set in/out prompts and printing system
689 self.displayhook = self.displayhook_class(
689 self.displayhook = self.displayhook_class(
690 parent=self,
690 parent=self,
691 shell=self,
691 shell=self,
692 cache_size=self.cache_size,
692 cache_size=self.cache_size,
693 )
693 )
694 self.configurables.append(self.displayhook)
694 self.configurables.append(self.displayhook)
695 # This is a context manager that installs/revmoes the displayhook at
695 # This is a context manager that installs/revmoes the displayhook at
696 # the appropriate time.
696 # the appropriate time.
697 self.display_trap = DisplayTrap(hook=self.displayhook)
697 self.display_trap = DisplayTrap(hook=self.displayhook)
698
698
699 def init_latextool(self):
699 def init_latextool(self):
700 """Configure LaTeXTool."""
700 """Configure LaTeXTool."""
701 cfg = LaTeXTool.instance(parent=self)
701 cfg = LaTeXTool.instance(parent=self)
702 if cfg not in self.configurables:
702 if cfg not in self.configurables:
703 self.configurables.append(cfg)
703 self.configurables.append(cfg)
704
704
705 def init_virtualenv(self):
705 def init_virtualenv(self):
706 """Add a virtualenv to sys.path so the user can import modules from it.
706 """Add a virtualenv to sys.path so the user can import modules from it.
707 This isn't perfect: it doesn't use the Python interpreter with which the
707 This isn't perfect: it doesn't use the Python interpreter with which the
708 virtualenv was built, and it ignores the --no-site-packages option. A
708 virtualenv was built, and it ignores the --no-site-packages option. A
709 warning will appear suggesting the user installs IPython in the
709 warning will appear suggesting the user installs IPython in the
710 virtualenv, but for many cases, it probably works well enough.
710 virtualenv, but for many cases, it probably works well enough.
711
711
712 Adapted from code snippets online.
712 Adapted from code snippets online.
713
713
714 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
714 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
715 """
715 """
716 if 'VIRTUAL_ENV' not in os.environ:
716 if 'VIRTUAL_ENV' not in os.environ:
717 # Not in a virtualenv
717 # Not in a virtualenv
718 return
718 return
719
719
720 # venv detection:
720 # venv detection:
721 # stdlib venv may symlink sys.executable, so we can't use realpath.
721 # stdlib venv may symlink sys.executable, so we can't use realpath.
722 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
722 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
723 # So we just check every item in the symlink tree (generally <= 3)
723 # So we just check every item in the symlink tree (generally <= 3)
724 p = sys.executable
724 p = sys.executable
725 paths = [p]
725 paths = [p]
726 while os.path.islink(p):
726 while os.path.islink(p):
727 p = os.path.join(os.path.dirname(p), os.readlink(p))
727 p = os.path.join(os.path.dirname(p), os.readlink(p))
728 paths.append(p)
728 paths.append(p)
729 if any(p.startswith(os.environ['VIRTUAL_ENV']) for p in paths):
729 if any(p.startswith(os.environ['VIRTUAL_ENV']) for p in paths):
730 # Running properly in the virtualenv, don't need to do anything
730 # Running properly in the virtualenv, don't need to do anything
731 return
731 return
732
732
733 warn("Attempting to work in a virtualenv. If you encounter problems, please "
733 warn("Attempting to work in a virtualenv. If you encounter problems, please "
734 "install IPython inside the virtualenv.")
734 "install IPython inside the virtualenv.")
735 if sys.platform == "win32":
735 if sys.platform == "win32":
736 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
736 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
737 else:
737 else:
738 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
738 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
739 'python%d.%d' % sys.version_info[:2], 'site-packages')
739 'python%d.%d' % sys.version_info[:2], 'site-packages')
740
740
741 import site
741 import site
742 sys.path.insert(0, virtual_env)
742 sys.path.insert(0, virtual_env)
743 site.addsitedir(virtual_env)
743 site.addsitedir(virtual_env)
744
744
745 #-------------------------------------------------------------------------
745 #-------------------------------------------------------------------------
746 # Things related to injections into the sys module
746 # Things related to injections into the sys module
747 #-------------------------------------------------------------------------
747 #-------------------------------------------------------------------------
748
748
749 def save_sys_module_state(self):
749 def save_sys_module_state(self):
750 """Save the state of hooks in the sys module.
750 """Save the state of hooks in the sys module.
751
751
752 This has to be called after self.user_module is created.
752 This has to be called after self.user_module is created.
753 """
753 """
754 self._orig_sys_module_state = {}
754 self._orig_sys_module_state = {}
755 self._orig_sys_module_state['stdin'] = sys.stdin
755 self._orig_sys_module_state['stdin'] = sys.stdin
756 self._orig_sys_module_state['stdout'] = sys.stdout
756 self._orig_sys_module_state['stdout'] = sys.stdout
757 self._orig_sys_module_state['stderr'] = sys.stderr
757 self._orig_sys_module_state['stderr'] = sys.stderr
758 self._orig_sys_module_state['excepthook'] = sys.excepthook
758 self._orig_sys_module_state['excepthook'] = sys.excepthook
759 self._orig_sys_modules_main_name = self.user_module.__name__
759 self._orig_sys_modules_main_name = self.user_module.__name__
760 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
760 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
761
761
762 def restore_sys_module_state(self):
762 def restore_sys_module_state(self):
763 """Restore the state of the sys module."""
763 """Restore the state of the sys module."""
764 try:
764 try:
765 for k, v in iteritems(self._orig_sys_module_state):
765 for k, v in iteritems(self._orig_sys_module_state):
766 setattr(sys, k, v)
766 setattr(sys, k, v)
767 except AttributeError:
767 except AttributeError:
768 pass
768 pass
769 # Reset what what done in self.init_sys_modules
769 # Reset what what done in self.init_sys_modules
770 if self._orig_sys_modules_main_mod is not None:
770 if self._orig_sys_modules_main_mod is not None:
771 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
771 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
772
772
773 #-------------------------------------------------------------------------
773 #-------------------------------------------------------------------------
774 # Things related to hooks
774 # Things related to hooks
775 #-------------------------------------------------------------------------
775 #-------------------------------------------------------------------------
776
776
777 def init_hooks(self):
777 def init_hooks(self):
778 # hooks holds pointers used for user-side customizations
778 # hooks holds pointers used for user-side customizations
779 self.hooks = Struct()
779 self.hooks = Struct()
780
780
781 self.strdispatchers = {}
781 self.strdispatchers = {}
782
782
783 # Set all default hooks, defined in the IPython.hooks module.
783 # Set all default hooks, defined in the IPython.hooks module.
784 hooks = IPython.core.hooks
784 hooks = IPython.core.hooks
785 for hook_name in hooks.__all__:
785 for hook_name in hooks.__all__:
786 # default hooks have priority 100, i.e. low; user hooks should have
786 # default hooks have priority 100, i.e. low; user hooks should have
787 # 0-100 priority
787 # 0-100 priority
788 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
788 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
789
789
790 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
790 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
791 """set_hook(name,hook) -> sets an internal IPython hook.
791 """set_hook(name,hook) -> sets an internal IPython hook.
792
792
793 IPython exposes some of its internal API as user-modifiable hooks. By
793 IPython exposes some of its internal API as user-modifiable hooks. By
794 adding your function to one of these hooks, you can modify IPython's
794 adding your function to one of these hooks, you can modify IPython's
795 behavior to call at runtime your own routines."""
795 behavior to call at runtime your own routines."""
796
796
797 # At some point in the future, this should validate the hook before it
797 # At some point in the future, this should validate the hook before it
798 # accepts it. Probably at least check that the hook takes the number
798 # accepts it. Probably at least check that the hook takes the number
799 # of args it's supposed to.
799 # of args it's supposed to.
800
800
801 f = types.MethodType(hook,self)
801 f = types.MethodType(hook,self)
802
802
803 # check if the hook is for strdispatcher first
803 # check if the hook is for strdispatcher first
804 if str_key is not None:
804 if str_key is not None:
805 sdp = self.strdispatchers.get(name, StrDispatch())
805 sdp = self.strdispatchers.get(name, StrDispatch())
806 sdp.add_s(str_key, f, priority )
806 sdp.add_s(str_key, f, priority )
807 self.strdispatchers[name] = sdp
807 self.strdispatchers[name] = sdp
808 return
808 return
809 if re_key is not None:
809 if re_key is not None:
810 sdp = self.strdispatchers.get(name, StrDispatch())
810 sdp = self.strdispatchers.get(name, StrDispatch())
811 sdp.add_re(re.compile(re_key), f, priority )
811 sdp.add_re(re.compile(re_key), f, priority )
812 self.strdispatchers[name] = sdp
812 self.strdispatchers[name] = sdp
813 return
813 return
814
814
815 dp = getattr(self.hooks, name, None)
815 dp = getattr(self.hooks, name, None)
816 if name not in IPython.core.hooks.__all__:
816 if name not in IPython.core.hooks.__all__:
817 print("Warning! Hook '%s' is not one of %s" % \
817 print("Warning! Hook '%s' is not one of %s" % \
818 (name, IPython.core.hooks.__all__ ))
818 (name, IPython.core.hooks.__all__ ))
819 if not dp:
819 if not dp:
820 dp = IPython.core.hooks.CommandChainDispatcher()
820 dp = IPython.core.hooks.CommandChainDispatcher()
821
821
822 try:
822 try:
823 dp.add(f,priority)
823 dp.add(f,priority)
824 except AttributeError:
824 except AttributeError:
825 # it was not commandchain, plain old func - replace
825 # it was not commandchain, plain old func - replace
826 dp = f
826 dp = f
827
827
828 setattr(self.hooks,name, dp)
828 setattr(self.hooks,name, dp)
829
829
830 def register_post_execute(self, func):
830 def register_post_execute(self, func):
831 """Register a function for calling after code execution.
831 """Register a function for calling after code execution.
832 """
832 """
833 if not callable(func):
833 if not callable(func):
834 raise ValueError('argument %s must be callable' % func)
834 raise ValueError('argument %s must be callable' % func)
835 self._post_execute[func] = True
835 self._post_execute[func] = True
836
836
837 #-------------------------------------------------------------------------
837 #-------------------------------------------------------------------------
838 # Things related to the "main" module
838 # Things related to the "main" module
839 #-------------------------------------------------------------------------
839 #-------------------------------------------------------------------------
840
840
841 def new_main_mod(self, filename, modname):
841 def new_main_mod(self, filename, modname):
842 """Return a new 'main' module object for user code execution.
842 """Return a new 'main' module object for user code execution.
843
843
844 ``filename`` should be the path of the script which will be run in the
844 ``filename`` should be the path of the script which will be run in the
845 module. Requests with the same filename will get the same module, with
845 module. Requests with the same filename will get the same module, with
846 its namespace cleared.
846 its namespace cleared.
847
847
848 ``modname`` should be the module name - normally either '__main__' or
848 ``modname`` should be the module name - normally either '__main__' or
849 the basename of the file without the extension.
849 the basename of the file without the extension.
850
850
851 When scripts are executed via %run, we must keep a reference to their
851 When scripts are executed via %run, we must keep a reference to their
852 __main__ module around so that Python doesn't
852 __main__ module around so that Python doesn't
853 clear it, rendering references to module globals useless.
853 clear it, rendering references to module globals useless.
854
854
855 This method keeps said reference in a private dict, keyed by the
855 This method keeps said reference in a private dict, keyed by the
856 absolute path of the script. This way, for multiple executions of the
856 absolute path of the script. This way, for multiple executions of the
857 same script we only keep one copy of the namespace (the last one),
857 same script we only keep one copy of the namespace (the last one),
858 thus preventing memory leaks from old references while allowing the
858 thus preventing memory leaks from old references while allowing the
859 objects from the last execution to be accessible.
859 objects from the last execution to be accessible.
860 """
860 """
861 filename = os.path.abspath(filename)
861 filename = os.path.abspath(filename)
862 try:
862 try:
863 main_mod = self._main_mod_cache[filename]
863 main_mod = self._main_mod_cache[filename]
864 except KeyError:
864 except KeyError:
865 main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
865 main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
866 doc="Module created for script run in IPython")
866 doc="Module created for script run in IPython")
867 else:
867 else:
868 main_mod.__dict__.clear()
868 main_mod.__dict__.clear()
869 main_mod.__name__ = modname
869 main_mod.__name__ = modname
870
870
871 main_mod.__file__ = filename
871 main_mod.__file__ = filename
872 # It seems pydoc (and perhaps others) needs any module instance to
872 # It seems pydoc (and perhaps others) needs any module instance to
873 # implement a __nonzero__ method
873 # implement a __nonzero__ method
874 main_mod.__nonzero__ = lambda : True
874 main_mod.__nonzero__ = lambda : True
875
875
876 return main_mod
876 return main_mod
877
877
878 def clear_main_mod_cache(self):
878 def clear_main_mod_cache(self):
879 """Clear the cache of main modules.
879 """Clear the cache of main modules.
880
880
881 Mainly for use by utilities like %reset.
881 Mainly for use by utilities like %reset.
882
882
883 Examples
883 Examples
884 --------
884 --------
885
885
886 In [15]: import IPython
886 In [15]: import IPython
887
887
888 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
888 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
889
889
890 In [17]: len(_ip._main_mod_cache) > 0
890 In [17]: len(_ip._main_mod_cache) > 0
891 Out[17]: True
891 Out[17]: True
892
892
893 In [18]: _ip.clear_main_mod_cache()
893 In [18]: _ip.clear_main_mod_cache()
894
894
895 In [19]: len(_ip._main_mod_cache) == 0
895 In [19]: len(_ip._main_mod_cache) == 0
896 Out[19]: True
896 Out[19]: True
897 """
897 """
898 self._main_mod_cache.clear()
898 self._main_mod_cache.clear()
899
899
900 #-------------------------------------------------------------------------
900 #-------------------------------------------------------------------------
901 # Things related to debugging
901 # Things related to debugging
902 #-------------------------------------------------------------------------
902 #-------------------------------------------------------------------------
903
903
904 def init_pdb(self):
904 def init_pdb(self):
905 # Set calling of pdb on exceptions
905 # Set calling of pdb on exceptions
906 # self.call_pdb is a property
906 # self.call_pdb is a property
907 self.call_pdb = self.pdb
907 self.call_pdb = self.pdb
908
908
909 def _get_call_pdb(self):
909 def _get_call_pdb(self):
910 return self._call_pdb
910 return self._call_pdb
911
911
912 def _set_call_pdb(self,val):
912 def _set_call_pdb(self,val):
913
913
914 if val not in (0,1,False,True):
914 if val not in (0,1,False,True):
915 raise ValueError('new call_pdb value must be boolean')
915 raise ValueError('new call_pdb value must be boolean')
916
916
917 # store value in instance
917 # store value in instance
918 self._call_pdb = val
918 self._call_pdb = val
919
919
920 # notify the actual exception handlers
920 # notify the actual exception handlers
921 self.InteractiveTB.call_pdb = val
921 self.InteractiveTB.call_pdb = val
922
922
923 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
923 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
924 'Control auto-activation of pdb at exceptions')
924 'Control auto-activation of pdb at exceptions')
925
925
926 def debugger(self,force=False):
926 def debugger(self,force=False):
927 """Call the pydb/pdb debugger.
927 """Call the pydb/pdb debugger.
928
928
929 Keywords:
929 Keywords:
930
930
931 - force(False): by default, this routine checks the instance call_pdb
931 - force(False): by default, this routine checks the instance call_pdb
932 flag and does not actually invoke the debugger if the flag is false.
932 flag and does not actually invoke the debugger if the flag is false.
933 The 'force' option forces the debugger to activate even if the flag
933 The 'force' option forces the debugger to activate even if the flag
934 is false.
934 is false.
935 """
935 """
936
936
937 if not (force or self.call_pdb):
937 if not (force or self.call_pdb):
938 return
938 return
939
939
940 if not hasattr(sys,'last_traceback'):
940 if not hasattr(sys,'last_traceback'):
941 error('No traceback has been produced, nothing to debug.')
941 error('No traceback has been produced, nothing to debug.')
942 return
942 return
943
943
944 # use pydb if available
944 # use pydb if available
945 if debugger.has_pydb:
945 if debugger.has_pydb:
946 from pydb import pm
946 from pydb import pm
947 else:
947 else:
948 # fallback to our internal debugger
948 # fallback to our internal debugger
949 pm = lambda : self.InteractiveTB.debugger(force=True)
949 pm = lambda : self.InteractiveTB.debugger(force=True)
950
950
951 with self.readline_no_record:
951 with self.readline_no_record:
952 pm()
952 pm()
953
953
954 #-------------------------------------------------------------------------
954 #-------------------------------------------------------------------------
955 # Things related to IPython's various namespaces
955 # Things related to IPython's various namespaces
956 #-------------------------------------------------------------------------
956 #-------------------------------------------------------------------------
957 default_user_namespaces = True
957 default_user_namespaces = True
958
958
959 def init_create_namespaces(self, user_module=None, user_ns=None):
959 def init_create_namespaces(self, user_module=None, user_ns=None):
960 # Create the namespace where the user will operate. user_ns is
960 # Create the namespace where the user will operate. user_ns is
961 # normally the only one used, and it is passed to the exec calls as
961 # normally the only one used, and it is passed to the exec calls as
962 # the locals argument. But we do carry a user_global_ns namespace
962 # the locals argument. But we do carry a user_global_ns namespace
963 # given as the exec 'globals' argument, This is useful in embedding
963 # given as the exec 'globals' argument, This is useful in embedding
964 # situations where the ipython shell opens in a context where the
964 # situations where the ipython shell opens in a context where the
965 # distinction between locals and globals is meaningful. For
965 # distinction between locals and globals is meaningful. For
966 # non-embedded contexts, it is just the same object as the user_ns dict.
966 # non-embedded contexts, it is just the same object as the user_ns dict.
967
967
968 # FIXME. For some strange reason, __builtins__ is showing up at user
968 # FIXME. For some strange reason, __builtins__ is showing up at user
969 # level as a dict instead of a module. This is a manual fix, but I
969 # level as a dict instead of a module. This is a manual fix, but I
970 # should really track down where the problem is coming from. Alex
970 # should really track down where the problem is coming from. Alex
971 # Schmolck reported this problem first.
971 # Schmolck reported this problem first.
972
972
973 # A useful post by Alex Martelli on this topic:
973 # A useful post by Alex Martelli on this topic:
974 # Re: inconsistent value from __builtins__
974 # Re: inconsistent value from __builtins__
975 # Von: Alex Martelli <aleaxit@yahoo.com>
975 # Von: Alex Martelli <aleaxit@yahoo.com>
976 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
976 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
977 # Gruppen: comp.lang.python
977 # Gruppen: comp.lang.python
978
978
979 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
979 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
980 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
980 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
981 # > <type 'dict'>
981 # > <type 'dict'>
982 # > >>> print type(__builtins__)
982 # > >>> print type(__builtins__)
983 # > <type 'module'>
983 # > <type 'module'>
984 # > Is this difference in return value intentional?
984 # > Is this difference in return value intentional?
985
985
986 # Well, it's documented that '__builtins__' can be either a dictionary
986 # Well, it's documented that '__builtins__' can be either a dictionary
987 # or a module, and it's been that way for a long time. Whether it's
987 # or a module, and it's been that way for a long time. Whether it's
988 # intentional (or sensible), I don't know. In any case, the idea is
988 # intentional (or sensible), I don't know. In any case, the idea is
989 # that if you need to access the built-in namespace directly, you
989 # that if you need to access the built-in namespace directly, you
990 # should start with "import __builtin__" (note, no 's') which will
990 # should start with "import __builtin__" (note, no 's') which will
991 # definitely give you a module. Yeah, it's somewhat confusing:-(.
991 # definitely give you a module. Yeah, it's somewhat confusing:-(.
992
992
993 # These routines return a properly built module and dict as needed by
993 # These routines return a properly built module and dict as needed by
994 # the rest of the code, and can also be used by extension writers to
994 # the rest of the code, and can also be used by extension writers to
995 # generate properly initialized namespaces.
995 # generate properly initialized namespaces.
996 if (user_ns is not None) or (user_module is not None):
996 if (user_ns is not None) or (user_module is not None):
997 self.default_user_namespaces = False
997 self.default_user_namespaces = False
998 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
998 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
999
999
1000 # A record of hidden variables we have added to the user namespace, so
1000 # A record of hidden variables we have added to the user namespace, so
1001 # we can list later only variables defined in actual interactive use.
1001 # we can list later only variables defined in actual interactive use.
1002 self.user_ns_hidden = {}
1002 self.user_ns_hidden = {}
1003
1003
1004 # Now that FakeModule produces a real module, we've run into a nasty
1004 # Now that FakeModule produces a real module, we've run into a nasty
1005 # problem: after script execution (via %run), the module where the user
1005 # problem: after script execution (via %run), the module where the user
1006 # code ran is deleted. Now that this object is a true module (needed
1006 # code ran is deleted. Now that this object is a true module (needed
1007 # so docetst and other tools work correctly), the Python module
1007 # so docetst and other tools work correctly), the Python module
1008 # teardown mechanism runs over it, and sets to None every variable
1008 # teardown mechanism runs over it, and sets to None every variable
1009 # present in that module. Top-level references to objects from the
1009 # present in that module. Top-level references to objects from the
1010 # script survive, because the user_ns is updated with them. However,
1010 # script survive, because the user_ns is updated with them. However,
1011 # calling functions defined in the script that use other things from
1011 # calling functions defined in the script that use other things from
1012 # the script will fail, because the function's closure had references
1012 # the script will fail, because the function's closure had references
1013 # to the original objects, which are now all None. So we must protect
1013 # to the original objects, which are now all None. So we must protect
1014 # these modules from deletion by keeping a cache.
1014 # these modules from deletion by keeping a cache.
1015 #
1015 #
1016 # To avoid keeping stale modules around (we only need the one from the
1016 # To avoid keeping stale modules around (we only need the one from the
1017 # last run), we use a dict keyed with the full path to the script, so
1017 # last run), we use a dict keyed with the full path to the script, so
1018 # only the last version of the module is held in the cache. Note,
1018 # only the last version of the module is held in the cache. Note,
1019 # however, that we must cache the module *namespace contents* (their
1019 # however, that we must cache the module *namespace contents* (their
1020 # __dict__). Because if we try to cache the actual modules, old ones
1020 # __dict__). Because if we try to cache the actual modules, old ones
1021 # (uncached) could be destroyed while still holding references (such as
1021 # (uncached) could be destroyed while still holding references (such as
1022 # those held by GUI objects that tend to be long-lived)>
1022 # those held by GUI objects that tend to be long-lived)>
1023 #
1023 #
1024 # The %reset command will flush this cache. See the cache_main_mod()
1024 # The %reset command will flush this cache. See the cache_main_mod()
1025 # and clear_main_mod_cache() methods for details on use.
1025 # and clear_main_mod_cache() methods for details on use.
1026
1026
1027 # This is the cache used for 'main' namespaces
1027 # This is the cache used for 'main' namespaces
1028 self._main_mod_cache = {}
1028 self._main_mod_cache = {}
1029
1029
1030 # A table holding all the namespaces IPython deals with, so that
1030 # A table holding all the namespaces IPython deals with, so that
1031 # introspection facilities can search easily.
1031 # introspection facilities can search easily.
1032 self.ns_table = {'user_global':self.user_module.__dict__,
1032 self.ns_table = {'user_global':self.user_module.__dict__,
1033 'user_local':self.user_ns,
1033 'user_local':self.user_ns,
1034 'builtin':builtin_mod.__dict__
1034 'builtin':builtin_mod.__dict__
1035 }
1035 }
1036
1036
1037 @property
1037 @property
1038 def user_global_ns(self):
1038 def user_global_ns(self):
1039 return self.user_module.__dict__
1039 return self.user_module.__dict__
1040
1040
1041 def prepare_user_module(self, user_module=None, user_ns=None):
1041 def prepare_user_module(self, user_module=None, user_ns=None):
1042 """Prepare the module and namespace in which user code will be run.
1042 """Prepare the module and namespace in which user code will be run.
1043
1043
1044 When IPython is started normally, both parameters are None: a new module
1044 When IPython is started normally, both parameters are None: a new module
1045 is created automatically, and its __dict__ used as the namespace.
1045 is created automatically, and its __dict__ used as the namespace.
1046
1046
1047 If only user_module is provided, its __dict__ is used as the namespace.
1047 If only user_module is provided, its __dict__ is used as the namespace.
1048 If only user_ns is provided, a dummy module is created, and user_ns
1048 If only user_ns is provided, a dummy module is created, and user_ns
1049 becomes the global namespace. If both are provided (as they may be
1049 becomes the global namespace. If both are provided (as they may be
1050 when embedding), user_ns is the local namespace, and user_module
1050 when embedding), user_ns is the local namespace, and user_module
1051 provides the global namespace.
1051 provides the global namespace.
1052
1052
1053 Parameters
1053 Parameters
1054 ----------
1054 ----------
1055 user_module : module, optional
1055 user_module : module, optional
1056 The current user module in which IPython is being run. If None,
1056 The current user module in which IPython is being run. If None,
1057 a clean module will be created.
1057 a clean module will be created.
1058 user_ns : dict, optional
1058 user_ns : dict, optional
1059 A namespace in which to run interactive commands.
1059 A namespace in which to run interactive commands.
1060
1060
1061 Returns
1061 Returns
1062 -------
1062 -------
1063 A tuple of user_module and user_ns, each properly initialised.
1063 A tuple of user_module and user_ns, each properly initialised.
1064 """
1064 """
1065 if user_module is None and user_ns is not None:
1065 if user_module is None and user_ns is not None:
1066 user_ns.setdefault("__name__", "__main__")
1066 user_ns.setdefault("__name__", "__main__")
1067 user_module = DummyMod()
1067 user_module = DummyMod()
1068 user_module.__dict__ = user_ns
1068 user_module.__dict__ = user_ns
1069
1069
1070 if user_module is None:
1070 if user_module is None:
1071 user_module = types.ModuleType("__main__",
1071 user_module = types.ModuleType("__main__",
1072 doc="Automatically created module for IPython interactive environment")
1072 doc="Automatically created module for IPython interactive environment")
1073
1073
1074 # We must ensure that __builtin__ (without the final 's') is always
1074 # We must ensure that __builtin__ (without the final 's') is always
1075 # available and pointing to the __builtin__ *module*. For more details:
1075 # available and pointing to the __builtin__ *module*. For more details:
1076 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1076 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1077 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1077 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1078 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1078 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1079
1079
1080 if user_ns is None:
1080 if user_ns is None:
1081 user_ns = user_module.__dict__
1081 user_ns = user_module.__dict__
1082
1082
1083 return user_module, user_ns
1083 return user_module, user_ns
1084
1084
1085 def init_sys_modules(self):
1085 def init_sys_modules(self):
1086 # We need to insert into sys.modules something that looks like a
1086 # We need to insert into sys.modules something that looks like a
1087 # module but which accesses the IPython namespace, for shelve and
1087 # module but which accesses the IPython namespace, for shelve and
1088 # pickle to work interactively. Normally they rely on getting
1088 # pickle to work interactively. Normally they rely on getting
1089 # everything out of __main__, but for embedding purposes each IPython
1089 # everything out of __main__, but for embedding purposes each IPython
1090 # instance has its own private namespace, so we can't go shoving
1090 # instance has its own private namespace, so we can't go shoving
1091 # everything into __main__.
1091 # everything into __main__.
1092
1092
1093 # note, however, that we should only do this for non-embedded
1093 # note, however, that we should only do this for non-embedded
1094 # ipythons, which really mimic the __main__.__dict__ with their own
1094 # ipythons, which really mimic the __main__.__dict__ with their own
1095 # namespace. Embedded instances, on the other hand, should not do
1095 # namespace. Embedded instances, on the other hand, should not do
1096 # this because they need to manage the user local/global namespaces
1096 # this because they need to manage the user local/global namespaces
1097 # only, but they live within a 'normal' __main__ (meaning, they
1097 # only, but they live within a 'normal' __main__ (meaning, they
1098 # shouldn't overtake the execution environment of the script they're
1098 # shouldn't overtake the execution environment of the script they're
1099 # embedded in).
1099 # embedded in).
1100
1100
1101 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1101 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1102 main_name = self.user_module.__name__
1102 main_name = self.user_module.__name__
1103 sys.modules[main_name] = self.user_module
1103 sys.modules[main_name] = self.user_module
1104
1104
1105 def init_user_ns(self):
1105 def init_user_ns(self):
1106 """Initialize all user-visible namespaces to their minimum defaults.
1106 """Initialize all user-visible namespaces to their minimum defaults.
1107
1107
1108 Certain history lists are also initialized here, as they effectively
1108 Certain history lists are also initialized here, as they effectively
1109 act as user namespaces.
1109 act as user namespaces.
1110
1110
1111 Notes
1111 Notes
1112 -----
1112 -----
1113 All data structures here are only filled in, they are NOT reset by this
1113 All data structures here are only filled in, they are NOT reset by this
1114 method. If they were not empty before, data will simply be added to
1114 method. If they were not empty before, data will simply be added to
1115 therm.
1115 therm.
1116 """
1116 """
1117 # This function works in two parts: first we put a few things in
1117 # This function works in two parts: first we put a few things in
1118 # user_ns, and we sync that contents into user_ns_hidden so that these
1118 # user_ns, and we sync that contents into user_ns_hidden so that these
1119 # initial variables aren't shown by %who. After the sync, we add the
1119 # initial variables aren't shown by %who. After the sync, we add the
1120 # rest of what we *do* want the user to see with %who even on a new
1120 # rest of what we *do* want the user to see with %who even on a new
1121 # session (probably nothing, so theye really only see their own stuff)
1121 # session (probably nothing, so theye really only see their own stuff)
1122
1122
1123 # The user dict must *always* have a __builtin__ reference to the
1123 # The user dict must *always* have a __builtin__ reference to the
1124 # Python standard __builtin__ namespace, which must be imported.
1124 # Python standard __builtin__ namespace, which must be imported.
1125 # This is so that certain operations in prompt evaluation can be
1125 # This is so that certain operations in prompt evaluation can be
1126 # reliably executed with builtins. Note that we can NOT use
1126 # reliably executed with builtins. Note that we can NOT use
1127 # __builtins__ (note the 's'), because that can either be a dict or a
1127 # __builtins__ (note the 's'), because that can either be a dict or a
1128 # module, and can even mutate at runtime, depending on the context
1128 # module, and can even mutate at runtime, depending on the context
1129 # (Python makes no guarantees on it). In contrast, __builtin__ is
1129 # (Python makes no guarantees on it). In contrast, __builtin__ is
1130 # always a module object, though it must be explicitly imported.
1130 # always a module object, though it must be explicitly imported.
1131
1131
1132 # For more details:
1132 # For more details:
1133 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1133 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1134 ns = dict()
1134 ns = dict()
1135
1135
1136 # make global variables for user access to the histories
1136 # make global variables for user access to the histories
1137 ns['_ih'] = self.history_manager.input_hist_parsed
1137 ns['_ih'] = self.history_manager.input_hist_parsed
1138 ns['_oh'] = self.history_manager.output_hist
1138 ns['_oh'] = self.history_manager.output_hist
1139 ns['_dh'] = self.history_manager.dir_hist
1139 ns['_dh'] = self.history_manager.dir_hist
1140
1140
1141 ns['_sh'] = shadowns
1141 ns['_sh'] = shadowns
1142
1142
1143 # user aliases to input and output histories. These shouldn't show up
1143 # user aliases to input and output histories. These shouldn't show up
1144 # in %who, as they can have very large reprs.
1144 # in %who, as they can have very large reprs.
1145 ns['In'] = self.history_manager.input_hist_parsed
1145 ns['In'] = self.history_manager.input_hist_parsed
1146 ns['Out'] = self.history_manager.output_hist
1146 ns['Out'] = self.history_manager.output_hist
1147
1147
1148 # Store myself as the public api!!!
1148 # Store myself as the public api!!!
1149 ns['get_ipython'] = self.get_ipython
1149 ns['get_ipython'] = self.get_ipython
1150
1150
1151 ns['exit'] = self.exiter
1151 ns['exit'] = self.exiter
1152 ns['quit'] = self.exiter
1152 ns['quit'] = self.exiter
1153
1153
1154 # Sync what we've added so far to user_ns_hidden so these aren't seen
1154 # Sync what we've added so far to user_ns_hidden so these aren't seen
1155 # by %who
1155 # by %who
1156 self.user_ns_hidden.update(ns)
1156 self.user_ns_hidden.update(ns)
1157
1157
1158 # Anything put into ns now would show up in %who. Think twice before
1158 # Anything put into ns now would show up in %who. Think twice before
1159 # putting anything here, as we really want %who to show the user their
1159 # putting anything here, as we really want %who to show the user their
1160 # stuff, not our variables.
1160 # stuff, not our variables.
1161
1161
1162 # Finally, update the real user's namespace
1162 # Finally, update the real user's namespace
1163 self.user_ns.update(ns)
1163 self.user_ns.update(ns)
1164
1164
1165 @property
1165 @property
1166 def all_ns_refs(self):
1166 def all_ns_refs(self):
1167 """Get a list of references to all the namespace dictionaries in which
1167 """Get a list of references to all the namespace dictionaries in which
1168 IPython might store a user-created object.
1168 IPython might store a user-created object.
1169
1169
1170 Note that this does not include the displayhook, which also caches
1170 Note that this does not include the displayhook, which also caches
1171 objects from the output."""
1171 objects from the output."""
1172 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1172 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1173 [m.__dict__ for m in self._main_mod_cache.values()]
1173 [m.__dict__ for m in self._main_mod_cache.values()]
1174
1174
1175 def reset(self, new_session=True):
1175 def reset(self, new_session=True):
1176 """Clear all internal namespaces, and attempt to release references to
1176 """Clear all internal namespaces, and attempt to release references to
1177 user objects.
1177 user objects.
1178
1178
1179 If new_session is True, a new history session will be opened.
1179 If new_session is True, a new history session will be opened.
1180 """
1180 """
1181 # Clear histories
1181 # Clear histories
1182 self.history_manager.reset(new_session)
1182 self.history_manager.reset(new_session)
1183 # Reset counter used to index all histories
1183 # Reset counter used to index all histories
1184 if new_session:
1184 if new_session:
1185 self.execution_count = 1
1185 self.execution_count = 1
1186
1186
1187 # Flush cached output items
1187 # Flush cached output items
1188 if self.displayhook.do_full_cache:
1188 if self.displayhook.do_full_cache:
1189 self.displayhook.flush()
1189 self.displayhook.flush()
1190
1190
1191 # The main execution namespaces must be cleared very carefully,
1191 # The main execution namespaces must be cleared very carefully,
1192 # skipping the deletion of the builtin-related keys, because doing so
1192 # skipping the deletion of the builtin-related keys, because doing so
1193 # would cause errors in many object's __del__ methods.
1193 # would cause errors in many object's __del__ methods.
1194 if self.user_ns is not self.user_global_ns:
1194 if self.user_ns is not self.user_global_ns:
1195 self.user_ns.clear()
1195 self.user_ns.clear()
1196 ns = self.user_global_ns
1196 ns = self.user_global_ns
1197 drop_keys = set(ns.keys())
1197 drop_keys = set(ns.keys())
1198 drop_keys.discard('__builtin__')
1198 drop_keys.discard('__builtin__')
1199 drop_keys.discard('__builtins__')
1199 drop_keys.discard('__builtins__')
1200 drop_keys.discard('__name__')
1200 drop_keys.discard('__name__')
1201 for k in drop_keys:
1201 for k in drop_keys:
1202 del ns[k]
1202 del ns[k]
1203
1203
1204 self.user_ns_hidden.clear()
1204 self.user_ns_hidden.clear()
1205
1205
1206 # Restore the user namespaces to minimal usability
1206 # Restore the user namespaces to minimal usability
1207 self.init_user_ns()
1207 self.init_user_ns()
1208
1208
1209 # Restore the default and user aliases
1209 # Restore the default and user aliases
1210 self.alias_manager.clear_aliases()
1210 self.alias_manager.clear_aliases()
1211 self.alias_manager.init_aliases()
1211 self.alias_manager.init_aliases()
1212
1212
1213 # Flush the private list of module references kept for script
1213 # Flush the private list of module references kept for script
1214 # execution protection
1214 # execution protection
1215 self.clear_main_mod_cache()
1215 self.clear_main_mod_cache()
1216
1216
1217 def del_var(self, varname, by_name=False):
1217 def del_var(self, varname, by_name=False):
1218 """Delete a variable from the various namespaces, so that, as
1218 """Delete a variable from the various namespaces, so that, as
1219 far as possible, we're not keeping any hidden references to it.
1219 far as possible, we're not keeping any hidden references to it.
1220
1220
1221 Parameters
1221 Parameters
1222 ----------
1222 ----------
1223 varname : str
1223 varname : str
1224 The name of the variable to delete.
1224 The name of the variable to delete.
1225 by_name : bool
1225 by_name : bool
1226 If True, delete variables with the given name in each
1226 If True, delete variables with the given name in each
1227 namespace. If False (default), find the variable in the user
1227 namespace. If False (default), find the variable in the user
1228 namespace, and delete references to it.
1228 namespace, and delete references to it.
1229 """
1229 """
1230 if varname in ('__builtin__', '__builtins__'):
1230 if varname in ('__builtin__', '__builtins__'):
1231 raise ValueError("Refusing to delete %s" % varname)
1231 raise ValueError("Refusing to delete %s" % varname)
1232
1232
1233 ns_refs = self.all_ns_refs
1233 ns_refs = self.all_ns_refs
1234
1234
1235 if by_name: # Delete by name
1235 if by_name: # Delete by name
1236 for ns in ns_refs:
1236 for ns in ns_refs:
1237 try:
1237 try:
1238 del ns[varname]
1238 del ns[varname]
1239 except KeyError:
1239 except KeyError:
1240 pass
1240 pass
1241 else: # Delete by object
1241 else: # Delete by object
1242 try:
1242 try:
1243 obj = self.user_ns[varname]
1243 obj = self.user_ns[varname]
1244 except KeyError:
1244 except KeyError:
1245 raise NameError("name '%s' is not defined" % varname)
1245 raise NameError("name '%s' is not defined" % varname)
1246 # Also check in output history
1246 # Also check in output history
1247 ns_refs.append(self.history_manager.output_hist)
1247 ns_refs.append(self.history_manager.output_hist)
1248 for ns in ns_refs:
1248 for ns in ns_refs:
1249 to_delete = [n for n, o in iteritems(ns) if o is obj]
1249 to_delete = [n for n, o in iteritems(ns) if o is obj]
1250 for name in to_delete:
1250 for name in to_delete:
1251 del ns[name]
1251 del ns[name]
1252
1252
1253 # displayhook keeps extra references, but not in a dictionary
1253 # displayhook keeps extra references, but not in a dictionary
1254 for name in ('_', '__', '___'):
1254 for name in ('_', '__', '___'):
1255 if getattr(self.displayhook, name) is obj:
1255 if getattr(self.displayhook, name) is obj:
1256 setattr(self.displayhook, name, None)
1256 setattr(self.displayhook, name, None)
1257
1257
1258 def reset_selective(self, regex=None):
1258 def reset_selective(self, regex=None):
1259 """Clear selective variables from internal namespaces based on a
1259 """Clear selective variables from internal namespaces based on a
1260 specified regular expression.
1260 specified regular expression.
1261
1261
1262 Parameters
1262 Parameters
1263 ----------
1263 ----------
1264 regex : string or compiled pattern, optional
1264 regex : string or compiled pattern, optional
1265 A regular expression pattern that will be used in searching
1265 A regular expression pattern that will be used in searching
1266 variable names in the users namespaces.
1266 variable names in the users namespaces.
1267 """
1267 """
1268 if regex is not None:
1268 if regex is not None:
1269 try:
1269 try:
1270 m = re.compile(regex)
1270 m = re.compile(regex)
1271 except TypeError:
1271 except TypeError:
1272 raise TypeError('regex must be a string or compiled pattern')
1272 raise TypeError('regex must be a string or compiled pattern')
1273 # Search for keys in each namespace that match the given regex
1273 # Search for keys in each namespace that match the given regex
1274 # If a match is found, delete the key/value pair.
1274 # If a match is found, delete the key/value pair.
1275 for ns in self.all_ns_refs:
1275 for ns in self.all_ns_refs:
1276 for var in ns:
1276 for var in ns:
1277 if m.search(var):
1277 if m.search(var):
1278 del ns[var]
1278 del ns[var]
1279
1279
1280 def push(self, variables, interactive=True):
1280 def push(self, variables, interactive=True):
1281 """Inject a group of variables into the IPython user namespace.
1281 """Inject a group of variables into the IPython user namespace.
1282
1282
1283 Parameters
1283 Parameters
1284 ----------
1284 ----------
1285 variables : dict, str or list/tuple of str
1285 variables : dict, str or list/tuple of str
1286 The variables to inject into the user's namespace. If a dict, a
1286 The variables to inject into the user's namespace. If a dict, a
1287 simple update is done. If a str, the string is assumed to have
1287 simple update is done. If a str, the string is assumed to have
1288 variable names separated by spaces. A list/tuple of str can also
1288 variable names separated by spaces. A list/tuple of str can also
1289 be used to give the variable names. If just the variable names are
1289 be used to give the variable names. If just the variable names are
1290 give (list/tuple/str) then the variable values looked up in the
1290 give (list/tuple/str) then the variable values looked up in the
1291 callers frame.
1291 callers frame.
1292 interactive : bool
1292 interactive : bool
1293 If True (default), the variables will be listed with the ``who``
1293 If True (default), the variables will be listed with the ``who``
1294 magic.
1294 magic.
1295 """
1295 """
1296 vdict = None
1296 vdict = None
1297
1297
1298 # We need a dict of name/value pairs to do namespace updates.
1298 # We need a dict of name/value pairs to do namespace updates.
1299 if isinstance(variables, dict):
1299 if isinstance(variables, dict):
1300 vdict = variables
1300 vdict = variables
1301 elif isinstance(variables, string_types+(list, tuple)):
1301 elif isinstance(variables, string_types+(list, tuple)):
1302 if isinstance(variables, string_types):
1302 if isinstance(variables, string_types):
1303 vlist = variables.split()
1303 vlist = variables.split()
1304 else:
1304 else:
1305 vlist = variables
1305 vlist = variables
1306 vdict = {}
1306 vdict = {}
1307 cf = sys._getframe(1)
1307 cf = sys._getframe(1)
1308 for name in vlist:
1308 for name in vlist:
1309 try:
1309 try:
1310 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1310 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1311 except:
1311 except:
1312 print('Could not get variable %s from %s' %
1312 print('Could not get variable %s from %s' %
1313 (name,cf.f_code.co_name))
1313 (name,cf.f_code.co_name))
1314 else:
1314 else:
1315 raise ValueError('variables must be a dict/str/list/tuple')
1315 raise ValueError('variables must be a dict/str/list/tuple')
1316
1316
1317 # Propagate variables to user namespace
1317 # Propagate variables to user namespace
1318 self.user_ns.update(vdict)
1318 self.user_ns.update(vdict)
1319
1319
1320 # And configure interactive visibility
1320 # And configure interactive visibility
1321 user_ns_hidden = self.user_ns_hidden
1321 user_ns_hidden = self.user_ns_hidden
1322 if interactive:
1322 if interactive:
1323 for name in vdict:
1323 for name in vdict:
1324 user_ns_hidden.pop(name, None)
1324 user_ns_hidden.pop(name, None)
1325 else:
1325 else:
1326 user_ns_hidden.update(vdict)
1326 user_ns_hidden.update(vdict)
1327
1327
1328 def drop_by_id(self, variables):
1328 def drop_by_id(self, variables):
1329 """Remove a dict of variables from the user namespace, if they are the
1329 """Remove a dict of variables from the user namespace, if they are the
1330 same as the values in the dictionary.
1330 same as the values in the dictionary.
1331
1331
1332 This is intended for use by extensions: variables that they've added can
1332 This is intended for use by extensions: variables that they've added can
1333 be taken back out if they are unloaded, without removing any that the
1333 be taken back out if they are unloaded, without removing any that the
1334 user has overwritten.
1334 user has overwritten.
1335
1335
1336 Parameters
1336 Parameters
1337 ----------
1337 ----------
1338 variables : dict
1338 variables : dict
1339 A dictionary mapping object names (as strings) to the objects.
1339 A dictionary mapping object names (as strings) to the objects.
1340 """
1340 """
1341 for name, obj in iteritems(variables):
1341 for name, obj in iteritems(variables):
1342 if name in self.user_ns and self.user_ns[name] is obj:
1342 if name in self.user_ns and self.user_ns[name] is obj:
1343 del self.user_ns[name]
1343 del self.user_ns[name]
1344 self.user_ns_hidden.pop(name, None)
1344 self.user_ns_hidden.pop(name, None)
1345
1345
1346 #-------------------------------------------------------------------------
1346 #-------------------------------------------------------------------------
1347 # Things related to object introspection
1347 # Things related to object introspection
1348 #-------------------------------------------------------------------------
1348 #-------------------------------------------------------------------------
1349
1349
1350 def _ofind(self, oname, namespaces=None):
1350 def _ofind(self, oname, namespaces=None):
1351 """Find an object in the available namespaces.
1351 """Find an object in the available namespaces.
1352
1352
1353 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1353 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1354
1354
1355 Has special code to detect magic functions.
1355 Has special code to detect magic functions.
1356 """
1356 """
1357 oname = oname.strip()
1357 oname = oname.strip()
1358 #print '1- oname: <%r>' % oname # dbg
1358 #print '1- oname: <%r>' % oname # dbg
1359 if not oname.startswith(ESC_MAGIC) and \
1359 if not oname.startswith(ESC_MAGIC) and \
1360 not oname.startswith(ESC_MAGIC2) and \
1360 not oname.startswith(ESC_MAGIC2) and \
1361 not py3compat.isidentifier(oname, dotted=True):
1361 not py3compat.isidentifier(oname, dotted=True):
1362 return dict(found=False)
1362 return dict(found=False)
1363
1363
1364 alias_ns = None
1364 alias_ns = None
1365 if namespaces is None:
1365 if namespaces is None:
1366 # Namespaces to search in:
1366 # Namespaces to search in:
1367 # Put them in a list. The order is important so that we
1367 # Put them in a list. The order is important so that we
1368 # find things in the same order that Python finds them.
1368 # find things in the same order that Python finds them.
1369 namespaces = [ ('Interactive', self.user_ns),
1369 namespaces = [ ('Interactive', self.user_ns),
1370 ('Interactive (global)', self.user_global_ns),
1370 ('Interactive (global)', self.user_global_ns),
1371 ('Python builtin', builtin_mod.__dict__),
1371 ('Python builtin', builtin_mod.__dict__),
1372 ]
1372 ]
1373
1373
1374 # initialize results to 'null'
1374 # initialize results to 'null'
1375 found = False; obj = None; ospace = None; ds = None;
1375 found = False; obj = None; ospace = None; ds = None;
1376 ismagic = False; isalias = False; parent = None
1376 ismagic = False; isalias = False; parent = None
1377
1377
1378 # We need to special-case 'print', which as of python2.6 registers as a
1378 # We need to special-case 'print', which as of python2.6 registers as a
1379 # function but should only be treated as one if print_function was
1379 # function but should only be treated as one if print_function was
1380 # loaded with a future import. In this case, just bail.
1380 # loaded with a future import. In this case, just bail.
1381 if (oname == 'print' and not py3compat.PY3 and not \
1381 if (oname == 'print' and not py3compat.PY3 and not \
1382 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1382 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1383 return {'found':found, 'obj':obj, 'namespace':ospace,
1383 return {'found':found, 'obj':obj, 'namespace':ospace,
1384 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1384 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1385
1385
1386 # Look for the given name by splitting it in parts. If the head is
1386 # Look for the given name by splitting it in parts. If the head is
1387 # found, then we look for all the remaining parts as members, and only
1387 # found, then we look for all the remaining parts as members, and only
1388 # declare success if we can find them all.
1388 # declare success if we can find them all.
1389 oname_parts = oname.split('.')
1389 oname_parts = oname.split('.')
1390 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1390 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1391 for nsname,ns in namespaces:
1391 for nsname,ns in namespaces:
1392 try:
1392 try:
1393 obj = ns[oname_head]
1393 obj = ns[oname_head]
1394 except KeyError:
1394 except KeyError:
1395 continue
1395 continue
1396 else:
1396 else:
1397 #print 'oname_rest:', oname_rest # dbg
1397 #print 'oname_rest:', oname_rest # dbg
1398 for part in oname_rest:
1398 for part in oname_rest:
1399 try:
1399 try:
1400 parent = obj
1400 parent = obj
1401 obj = getattr(obj,part)
1401 obj = getattr(obj,part)
1402 except:
1402 except:
1403 # Blanket except b/c some badly implemented objects
1403 # Blanket except b/c some badly implemented objects
1404 # allow __getattr__ to raise exceptions other than
1404 # allow __getattr__ to raise exceptions other than
1405 # AttributeError, which then crashes IPython.
1405 # AttributeError, which then crashes IPython.
1406 break
1406 break
1407 else:
1407 else:
1408 # If we finish the for loop (no break), we got all members
1408 # If we finish the for loop (no break), we got all members
1409 found = True
1409 found = True
1410 ospace = nsname
1410 ospace = nsname
1411 break # namespace loop
1411 break # namespace loop
1412
1412
1413 # Try to see if it's magic
1413 # Try to see if it's magic
1414 if not found:
1414 if not found:
1415 obj = None
1415 obj = None
1416 if oname.startswith(ESC_MAGIC2):
1416 if oname.startswith(ESC_MAGIC2):
1417 oname = oname.lstrip(ESC_MAGIC2)
1417 oname = oname.lstrip(ESC_MAGIC2)
1418 obj = self.find_cell_magic(oname)
1418 obj = self.find_cell_magic(oname)
1419 elif oname.startswith(ESC_MAGIC):
1419 elif oname.startswith(ESC_MAGIC):
1420 oname = oname.lstrip(ESC_MAGIC)
1420 oname = oname.lstrip(ESC_MAGIC)
1421 obj = self.find_line_magic(oname)
1421 obj = self.find_line_magic(oname)
1422 else:
1422 else:
1423 # search without prefix, so run? will find %run?
1423 # search without prefix, so run? will find %run?
1424 obj = self.find_line_magic(oname)
1424 obj = self.find_line_magic(oname)
1425 if obj is None:
1425 if obj is None:
1426 obj = self.find_cell_magic(oname)
1426 obj = self.find_cell_magic(oname)
1427 if obj is not None:
1427 if obj is not None:
1428 found = True
1428 found = True
1429 ospace = 'IPython internal'
1429 ospace = 'IPython internal'
1430 ismagic = True
1430 ismagic = True
1431
1431
1432 # Last try: special-case some literals like '', [], {}, etc:
1432 # Last try: special-case some literals like '', [], {}, etc:
1433 if not found and oname_head in ["''",'""','[]','{}','()']:
1433 if not found and oname_head in ["''",'""','[]','{}','()']:
1434 obj = eval(oname_head)
1434 obj = eval(oname_head)
1435 found = True
1435 found = True
1436 ospace = 'Interactive'
1436 ospace = 'Interactive'
1437
1437
1438 return {'found':found, 'obj':obj, 'namespace':ospace,
1438 return {'found':found, 'obj':obj, 'namespace':ospace,
1439 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1439 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1440
1440
1441 def _ofind_property(self, oname, info):
1441 def _ofind_property(self, oname, info):
1442 """Second part of object finding, to look for property details."""
1442 """Second part of object finding, to look for property details."""
1443 if info.found:
1443 if info.found:
1444 # Get the docstring of the class property if it exists.
1444 # Get the docstring of the class property if it exists.
1445 path = oname.split('.')
1445 path = oname.split('.')
1446 root = '.'.join(path[:-1])
1446 root = '.'.join(path[:-1])
1447 if info.parent is not None:
1447 if info.parent is not None:
1448 try:
1448 try:
1449 target = getattr(info.parent, '__class__')
1449 target = getattr(info.parent, '__class__')
1450 # The object belongs to a class instance.
1450 # The object belongs to a class instance.
1451 try:
1451 try:
1452 target = getattr(target, path[-1])
1452 target = getattr(target, path[-1])
1453 # The class defines the object.
1453 # The class defines the object.
1454 if isinstance(target, property):
1454 if isinstance(target, property):
1455 oname = root + '.__class__.' + path[-1]
1455 oname = root + '.__class__.' + path[-1]
1456 info = Struct(self._ofind(oname))
1456 info = Struct(self._ofind(oname))
1457 except AttributeError: pass
1457 except AttributeError: pass
1458 except AttributeError: pass
1458 except AttributeError: pass
1459
1459
1460 # We return either the new info or the unmodified input if the object
1460 # We return either the new info or the unmodified input if the object
1461 # hadn't been found
1461 # hadn't been found
1462 return info
1462 return info
1463
1463
1464 def _object_find(self, oname, namespaces=None):
1464 def _object_find(self, oname, namespaces=None):
1465 """Find an object and return a struct with info about it."""
1465 """Find an object and return a struct with info about it."""
1466 inf = Struct(self._ofind(oname, namespaces))
1466 inf = Struct(self._ofind(oname, namespaces))
1467 return Struct(self._ofind_property(oname, inf))
1467 return Struct(self._ofind_property(oname, inf))
1468
1468
1469 def _inspect(self, meth, oname, namespaces=None, **kw):
1469 def _inspect(self, meth, oname, namespaces=None, **kw):
1470 """Generic interface to the inspector system.
1470 """Generic interface to the inspector system.
1471
1471
1472 This function is meant to be called by pdef, pdoc & friends."""
1472 This function is meant to be called by pdef, pdoc & friends."""
1473 info = self._object_find(oname, namespaces)
1473 info = self._object_find(oname, namespaces)
1474 if info.found:
1474 if info.found:
1475 pmethod = getattr(self.inspector, meth)
1475 pmethod = getattr(self.inspector, meth)
1476 formatter = format_screen if info.ismagic else None
1476 formatter = format_screen if info.ismagic else None
1477 if meth == 'pdoc':
1477 if meth == 'pdoc':
1478 pmethod(info.obj, oname, formatter)
1478 pmethod(info.obj, oname, formatter)
1479 elif meth == 'pinfo':
1479 elif meth == 'pinfo':
1480 pmethod(info.obj, oname, formatter, info, **kw)
1480 pmethod(info.obj, oname, formatter, info, **kw)
1481 else:
1481 else:
1482 pmethod(info.obj, oname)
1482 pmethod(info.obj, oname)
1483 else:
1483 else:
1484 print('Object `%s` not found.' % oname)
1484 print('Object `%s` not found.' % oname)
1485 return 'not found' # so callers can take other action
1485 return 'not found' # so callers can take other action
1486
1486
1487 def object_inspect(self, oname, detail_level=0):
1487 def object_inspect(self, oname, detail_level=0):
1488 with self.builtin_trap:
1488 with self.builtin_trap:
1489 info = self._object_find(oname)
1489 info = self._object_find(oname)
1490 if info.found:
1490 if info.found:
1491 return self.inspector.info(info.obj, oname, info=info,
1491 return self.inspector.info(info.obj, oname, info=info,
1492 detail_level=detail_level
1492 detail_level=detail_level
1493 )
1493 )
1494 else:
1494 else:
1495 return oinspect.object_info(name=oname, found=False)
1495 return oinspect.object_info(name=oname, found=False)
1496
1496
1497 #-------------------------------------------------------------------------
1497 #-------------------------------------------------------------------------
1498 # Things related to history management
1498 # Things related to history management
1499 #-------------------------------------------------------------------------
1499 #-------------------------------------------------------------------------
1500
1500
1501 def init_history(self):
1501 def init_history(self):
1502 """Sets up the command history, and starts regular autosaves."""
1502 """Sets up the command history, and starts regular autosaves."""
1503 self.history_manager = HistoryManager(shell=self, parent=self)
1503 self.history_manager = HistoryManager(shell=self, parent=self)
1504 self.configurables.append(self.history_manager)
1504 self.configurables.append(self.history_manager)
1505
1505
1506 #-------------------------------------------------------------------------
1506 #-------------------------------------------------------------------------
1507 # Things related to exception handling and tracebacks (not debugging)
1507 # Things related to exception handling and tracebacks (not debugging)
1508 #-------------------------------------------------------------------------
1508 #-------------------------------------------------------------------------
1509
1509
1510 def init_traceback_handlers(self, custom_exceptions):
1510 def init_traceback_handlers(self, custom_exceptions):
1511 # Syntax error handler.
1511 # Syntax error handler.
1512 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1512 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1513
1513
1514 # The interactive one is initialized with an offset, meaning we always
1514 # The interactive one is initialized with an offset, meaning we always
1515 # want to remove the topmost item in the traceback, which is our own
1515 # want to remove the topmost item in the traceback, which is our own
1516 # internal code. Valid modes: ['Plain','Context','Verbose']
1516 # internal code. Valid modes: ['Plain','Context','Verbose']
1517 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1517 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1518 color_scheme='NoColor',
1518 color_scheme='NoColor',
1519 tb_offset = 1,
1519 tb_offset = 1,
1520 check_cache=check_linecache_ipython)
1520 check_cache=check_linecache_ipython)
1521
1521
1522 # The instance will store a pointer to the system-wide exception hook,
1522 # The instance will store a pointer to the system-wide exception hook,
1523 # so that runtime code (such as magics) can access it. This is because
1523 # so that runtime code (such as magics) can access it. This is because
1524 # during the read-eval loop, it may get temporarily overwritten.
1524 # during the read-eval loop, it may get temporarily overwritten.
1525 self.sys_excepthook = sys.excepthook
1525 self.sys_excepthook = sys.excepthook
1526
1526
1527 # and add any custom exception handlers the user may have specified
1527 # and add any custom exception handlers the user may have specified
1528 self.set_custom_exc(*custom_exceptions)
1528 self.set_custom_exc(*custom_exceptions)
1529
1529
1530 # Set the exception mode
1530 # Set the exception mode
1531 self.InteractiveTB.set_mode(mode=self.xmode)
1531 self.InteractiveTB.set_mode(mode=self.xmode)
1532
1532
1533 def set_custom_exc(self, exc_tuple, handler):
1533 def set_custom_exc(self, exc_tuple, handler):
1534 """set_custom_exc(exc_tuple,handler)
1534 """set_custom_exc(exc_tuple,handler)
1535
1535
1536 Set a custom exception handler, which will be called if any of the
1536 Set a custom exception handler, which will be called if any of the
1537 exceptions in exc_tuple occur in the mainloop (specifically, in the
1537 exceptions in exc_tuple occur in the mainloop (specifically, in the
1538 run_code() method).
1538 run_code() method).
1539
1539
1540 Parameters
1540 Parameters
1541 ----------
1541 ----------
1542
1542
1543 exc_tuple : tuple of exception classes
1543 exc_tuple : tuple of exception classes
1544 A *tuple* of exception classes, for which to call the defined
1544 A *tuple* of exception classes, for which to call the defined
1545 handler. It is very important that you use a tuple, and NOT A
1545 handler. It is very important that you use a tuple, and NOT A
1546 LIST here, because of the way Python's except statement works. If
1546 LIST here, because of the way Python's except statement works. If
1547 you only want to trap a single exception, use a singleton tuple::
1547 you only want to trap a single exception, use a singleton tuple::
1548
1548
1549 exc_tuple == (MyCustomException,)
1549 exc_tuple == (MyCustomException,)
1550
1550
1551 handler : callable
1551 handler : callable
1552 handler must have the following signature::
1552 handler must have the following signature::
1553
1553
1554 def my_handler(self, etype, value, tb, tb_offset=None):
1554 def my_handler(self, etype, value, tb, tb_offset=None):
1555 ...
1555 ...
1556 return structured_traceback
1556 return structured_traceback
1557
1557
1558 Your handler must return a structured traceback (a list of strings),
1558 Your handler must return a structured traceback (a list of strings),
1559 or None.
1559 or None.
1560
1560
1561 This will be made into an instance method (via types.MethodType)
1561 This will be made into an instance method (via types.MethodType)
1562 of IPython itself, and it will be called if any of the exceptions
1562 of IPython itself, and it will be called if any of the exceptions
1563 listed in the exc_tuple are caught. If the handler is None, an
1563 listed in the exc_tuple are caught. If the handler is None, an
1564 internal basic one is used, which just prints basic info.
1564 internal basic one is used, which just prints basic info.
1565
1565
1566 To protect IPython from crashes, if your handler ever raises an
1566 To protect IPython from crashes, if your handler ever raises an
1567 exception or returns an invalid result, it will be immediately
1567 exception or returns an invalid result, it will be immediately
1568 disabled.
1568 disabled.
1569
1569
1570 WARNING: by putting in your own exception handler into IPython's main
1570 WARNING: by putting in your own exception handler into IPython's main
1571 execution loop, you run a very good chance of nasty crashes. This
1571 execution loop, you run a very good chance of nasty crashes. This
1572 facility should only be used if you really know what you are doing."""
1572 facility should only be used if you really know what you are doing."""
1573
1573
1574 assert type(exc_tuple)==type(()) , \
1574 assert type(exc_tuple)==type(()) , \
1575 "The custom exceptions must be given AS A TUPLE."
1575 "The custom exceptions must be given AS A TUPLE."
1576
1576
1577 def dummy_handler(self,etype,value,tb,tb_offset=None):
1577 def dummy_handler(self,etype,value,tb,tb_offset=None):
1578 print('*** Simple custom exception handler ***')
1578 print('*** Simple custom exception handler ***')
1579 print('Exception type :',etype)
1579 print('Exception type :',etype)
1580 print('Exception value:',value)
1580 print('Exception value:',value)
1581 print('Traceback :',tb)
1581 print('Traceback :',tb)
1582 #print 'Source code :','\n'.join(self.buffer)
1582 #print 'Source code :','\n'.join(self.buffer)
1583
1583
1584 def validate_stb(stb):
1584 def validate_stb(stb):
1585 """validate structured traceback return type
1585 """validate structured traceback return type
1586
1586
1587 return type of CustomTB *should* be a list of strings, but allow
1587 return type of CustomTB *should* be a list of strings, but allow
1588 single strings or None, which are harmless.
1588 single strings or None, which are harmless.
1589
1589
1590 This function will *always* return a list of strings,
1590 This function will *always* return a list of strings,
1591 and will raise a TypeError if stb is inappropriate.
1591 and will raise a TypeError if stb is inappropriate.
1592 """
1592 """
1593 msg = "CustomTB must return list of strings, not %r" % stb
1593 msg = "CustomTB must return list of strings, not %r" % stb
1594 if stb is None:
1594 if stb is None:
1595 return []
1595 return []
1596 elif isinstance(stb, string_types):
1596 elif isinstance(stb, string_types):
1597 return [stb]
1597 return [stb]
1598 elif not isinstance(stb, list):
1598 elif not isinstance(stb, list):
1599 raise TypeError(msg)
1599 raise TypeError(msg)
1600 # it's a list
1600 # it's a list
1601 for line in stb:
1601 for line in stb:
1602 # check every element
1602 # check every element
1603 if not isinstance(line, string_types):
1603 if not isinstance(line, string_types):
1604 raise TypeError(msg)
1604 raise TypeError(msg)
1605 return stb
1605 return stb
1606
1606
1607 if handler is None:
1607 if handler is None:
1608 wrapped = dummy_handler
1608 wrapped = dummy_handler
1609 else:
1609 else:
1610 def wrapped(self,etype,value,tb,tb_offset=None):
1610 def wrapped(self,etype,value,tb,tb_offset=None):
1611 """wrap CustomTB handler, to protect IPython from user code
1611 """wrap CustomTB handler, to protect IPython from user code
1612
1612
1613 This makes it harder (but not impossible) for custom exception
1613 This makes it harder (but not impossible) for custom exception
1614 handlers to crash IPython.
1614 handlers to crash IPython.
1615 """
1615 """
1616 try:
1616 try:
1617 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1617 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1618 return validate_stb(stb)
1618 return validate_stb(stb)
1619 except:
1619 except:
1620 # clear custom handler immediately
1620 # clear custom handler immediately
1621 self.set_custom_exc((), None)
1621 self.set_custom_exc((), None)
1622 print("Custom TB Handler failed, unregistering", file=io.stderr)
1622 print("Custom TB Handler failed, unregistering", file=io.stderr)
1623 # show the exception in handler first
1623 # show the exception in handler first
1624 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1624 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1625 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1625 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1626 print("The original exception:", file=io.stdout)
1626 print("The original exception:", file=io.stdout)
1627 stb = self.InteractiveTB.structured_traceback(
1627 stb = self.InteractiveTB.structured_traceback(
1628 (etype,value,tb), tb_offset=tb_offset
1628 (etype,value,tb), tb_offset=tb_offset
1629 )
1629 )
1630 return stb
1630 return stb
1631
1631
1632 self.CustomTB = types.MethodType(wrapped,self)
1632 self.CustomTB = types.MethodType(wrapped,self)
1633 self.custom_exceptions = exc_tuple
1633 self.custom_exceptions = exc_tuple
1634
1634
1635 def excepthook(self, etype, value, tb):
1635 def excepthook(self, etype, value, tb):
1636 """One more defense for GUI apps that call sys.excepthook.
1636 """One more defense for GUI apps that call sys.excepthook.
1637
1637
1638 GUI frameworks like wxPython trap exceptions and call
1638 GUI frameworks like wxPython trap exceptions and call
1639 sys.excepthook themselves. I guess this is a feature that
1639 sys.excepthook themselves. I guess this is a feature that
1640 enables them to keep running after exceptions that would
1640 enables them to keep running after exceptions that would
1641 otherwise kill their mainloop. This is a bother for IPython
1641 otherwise kill their mainloop. This is a bother for IPython
1642 which excepts to catch all of the program exceptions with a try:
1642 which excepts to catch all of the program exceptions with a try:
1643 except: statement.
1643 except: statement.
1644
1644
1645 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1645 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1646 any app directly invokes sys.excepthook, it will look to the user like
1646 any app directly invokes sys.excepthook, it will look to the user like
1647 IPython crashed. In order to work around this, we can disable the
1647 IPython crashed. In order to work around this, we can disable the
1648 CrashHandler and replace it with this excepthook instead, which prints a
1648 CrashHandler and replace it with this excepthook instead, which prints a
1649 regular traceback using our InteractiveTB. In this fashion, apps which
1649 regular traceback using our InteractiveTB. In this fashion, apps which
1650 call sys.excepthook will generate a regular-looking exception from
1650 call sys.excepthook will generate a regular-looking exception from
1651 IPython, and the CrashHandler will only be triggered by real IPython
1651 IPython, and the CrashHandler will only be triggered by real IPython
1652 crashes.
1652 crashes.
1653
1653
1654 This hook should be used sparingly, only in places which are not likely
1654 This hook should be used sparingly, only in places which are not likely
1655 to be true IPython errors.
1655 to be true IPython errors.
1656 """
1656 """
1657 self.showtraceback((etype,value,tb),tb_offset=0)
1657 self.showtraceback((etype,value,tb),tb_offset=0)
1658
1658
1659 def _get_exc_info(self, exc_tuple=None):
1659 def _get_exc_info(self, exc_tuple=None):
1660 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1660 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1661
1661
1662 Ensures sys.last_type,value,traceback hold the exc_info we found,
1662 Ensures sys.last_type,value,traceback hold the exc_info we found,
1663 from whichever source.
1663 from whichever source.
1664
1664
1665 raises ValueError if none of these contain any information
1665 raises ValueError if none of these contain any information
1666 """
1666 """
1667 if exc_tuple is None:
1667 if exc_tuple is None:
1668 etype, value, tb = sys.exc_info()
1668 etype, value, tb = sys.exc_info()
1669 else:
1669 else:
1670 etype, value, tb = exc_tuple
1670 etype, value, tb = exc_tuple
1671
1671
1672 if etype is None:
1672 if etype is None:
1673 if hasattr(sys, 'last_type'):
1673 if hasattr(sys, 'last_type'):
1674 etype, value, tb = sys.last_type, sys.last_value, \
1674 etype, value, tb = sys.last_type, sys.last_value, \
1675 sys.last_traceback
1675 sys.last_traceback
1676
1676
1677 if etype is None:
1677 if etype is None:
1678 raise ValueError("No exception to find")
1678 raise ValueError("No exception to find")
1679
1679
1680 # Now store the exception info in sys.last_type etc.
1680 # Now store the exception info in sys.last_type etc.
1681 # WARNING: these variables are somewhat deprecated and not
1681 # WARNING: these variables are somewhat deprecated and not
1682 # necessarily safe to use in a threaded environment, but tools
1682 # necessarily safe to use in a threaded environment, but tools
1683 # like pdb depend on their existence, so let's set them. If we
1683 # like pdb depend on their existence, so let's set them. If we
1684 # find problems in the field, we'll need to revisit their use.
1684 # find problems in the field, we'll need to revisit their use.
1685 sys.last_type = etype
1685 sys.last_type = etype
1686 sys.last_value = value
1686 sys.last_value = value
1687 sys.last_traceback = tb
1687 sys.last_traceback = tb
1688
1688
1689 return etype, value, tb
1689 return etype, value, tb
1690
1690
1691 def show_usage_error(self, exc):
1691 def show_usage_error(self, exc):
1692 """Show a short message for UsageErrors
1692 """Show a short message for UsageErrors
1693
1693
1694 These are special exceptions that shouldn't show a traceback.
1694 These are special exceptions that shouldn't show a traceback.
1695 """
1695 """
1696 self.write_err("UsageError: %s" % exc)
1696 self.write_err("UsageError: %s" % exc)
1697
1697
1698 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1698 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1699 exception_only=False):
1699 exception_only=False):
1700 """Display the exception that just occurred.
1700 """Display the exception that just occurred.
1701
1701
1702 If nothing is known about the exception, this is the method which
1702 If nothing is known about the exception, this is the method which
1703 should be used throughout the code for presenting user tracebacks,
1703 should be used throughout the code for presenting user tracebacks,
1704 rather than directly invoking the InteractiveTB object.
1704 rather than directly invoking the InteractiveTB object.
1705
1705
1706 A specific showsyntaxerror() also exists, but this method can take
1706 A specific showsyntaxerror() also exists, but this method can take
1707 care of calling it if needed, so unless you are explicitly catching a
1707 care of calling it if needed, so unless you are explicitly catching a
1708 SyntaxError exception, don't try to analyze the stack manually and
1708 SyntaxError exception, don't try to analyze the stack manually and
1709 simply call this method."""
1709 simply call this method."""
1710
1710
1711 try:
1711 try:
1712 try:
1712 try:
1713 etype, value, tb = self._get_exc_info(exc_tuple)
1713 etype, value, tb = self._get_exc_info(exc_tuple)
1714 except ValueError:
1714 except ValueError:
1715 self.write_err('No traceback available to show.\n')
1715 self.write_err('No traceback available to show.\n')
1716 return
1716 return
1717
1717
1718 if issubclass(etype, SyntaxError):
1718 if issubclass(etype, SyntaxError):
1719 # Though this won't be called by syntax errors in the input
1719 # Though this won't be called by syntax errors in the input
1720 # line, there may be SyntaxError cases with imported code.
1720 # line, there may be SyntaxError cases with imported code.
1721 self.showsyntaxerror(filename)
1721 self.showsyntaxerror(filename)
1722 elif etype is UsageError:
1722 elif etype is UsageError:
1723 self.show_usage_error(value)
1723 self.show_usage_error(value)
1724 else:
1724 else:
1725 if exception_only:
1725 if exception_only:
1726 stb = ['An exception has occurred, use %tb to see '
1726 stb = ['An exception has occurred, use %tb to see '
1727 'the full traceback.\n']
1727 'the full traceback.\n']
1728 stb.extend(self.InteractiveTB.get_exception_only(etype,
1728 stb.extend(self.InteractiveTB.get_exception_only(etype,
1729 value))
1729 value))
1730 else:
1730 else:
1731 try:
1731 try:
1732 # Exception classes can customise their traceback - we
1732 # Exception classes can customise their traceback - we
1733 # use this in IPython.parallel for exceptions occurring
1733 # use this in IPython.parallel for exceptions occurring
1734 # in the engines. This should return a list of strings.
1734 # in the engines. This should return a list of strings.
1735 stb = value._render_traceback_()
1735 stb = value._render_traceback_()
1736 except Exception:
1736 except Exception:
1737 stb = self.InteractiveTB.structured_traceback(etype,
1737 stb = self.InteractiveTB.structured_traceback(etype,
1738 value, tb, tb_offset=tb_offset)
1738 value, tb, tb_offset=tb_offset)
1739
1739
1740 self._showtraceback(etype, value, stb)
1740 self._showtraceback(etype, value, stb)
1741 if self.call_pdb:
1741 if self.call_pdb:
1742 # drop into debugger
1742 # drop into debugger
1743 self.debugger(force=True)
1743 self.debugger(force=True)
1744 return
1744 return
1745
1745
1746 # Actually show the traceback
1746 # Actually show the traceback
1747 self._showtraceback(etype, value, stb)
1747 self._showtraceback(etype, value, stb)
1748
1748
1749 except KeyboardInterrupt:
1749 except KeyboardInterrupt:
1750 self.write_err("\nKeyboardInterrupt\n")
1750 self.write_err("\nKeyboardInterrupt\n")
1751
1751
1752 def _showtraceback(self, etype, evalue, stb):
1752 def _showtraceback(self, etype, evalue, stb):
1753 """Actually show a traceback.
1753 """Actually show a traceback.
1754
1754
1755 Subclasses may override this method to put the traceback on a different
1755 Subclasses may override this method to put the traceback on a different
1756 place, like a side channel.
1756 place, like a side channel.
1757 """
1757 """
1758 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1758 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1759
1759
1760 def showsyntaxerror(self, filename=None):
1760 def showsyntaxerror(self, filename=None):
1761 """Display the syntax error that just occurred.
1761 """Display the syntax error that just occurred.
1762
1762
1763 This doesn't display a stack trace because there isn't one.
1763 This doesn't display a stack trace because there isn't one.
1764
1764
1765 If a filename is given, it is stuffed in the exception instead
1765 If a filename is given, it is stuffed in the exception instead
1766 of what was there before (because Python's parser always uses
1766 of what was there before (because Python's parser always uses
1767 "<string>" when reading from a string).
1767 "<string>" when reading from a string).
1768 """
1768 """
1769 etype, value, last_traceback = self._get_exc_info()
1769 etype, value, last_traceback = self._get_exc_info()
1770
1770
1771 if filename and issubclass(etype, SyntaxError):
1771 if filename and issubclass(etype, SyntaxError):
1772 try:
1772 try:
1773 value.filename = filename
1773 value.filename = filename
1774 except:
1774 except:
1775 # Not the format we expect; leave it alone
1775 # Not the format we expect; leave it alone
1776 pass
1776 pass
1777
1777
1778 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1778 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1779 self._showtraceback(etype, value, stb)
1779 self._showtraceback(etype, value, stb)
1780
1780
1781 # This is overridden in TerminalInteractiveShell to show a message about
1781 # This is overridden in TerminalInteractiveShell to show a message about
1782 # the %paste magic.
1782 # the %paste magic.
1783 def showindentationerror(self):
1783 def showindentationerror(self):
1784 """Called by run_cell when there's an IndentationError in code entered
1784 """Called by run_cell when there's an IndentationError in code entered
1785 at the prompt.
1785 at the prompt.
1786
1786
1787 This is overridden in TerminalInteractiveShell to show a message about
1787 This is overridden in TerminalInteractiveShell to show a message about
1788 the %paste magic."""
1788 the %paste magic."""
1789 self.showsyntaxerror()
1789 self.showsyntaxerror()
1790
1790
1791 #-------------------------------------------------------------------------
1791 #-------------------------------------------------------------------------
1792 # Things related to readline
1792 # Things related to readline
1793 #-------------------------------------------------------------------------
1793 #-------------------------------------------------------------------------
1794
1794
1795 def init_readline(self):
1795 def init_readline(self):
1796 """Command history completion/saving/reloading."""
1796 """Command history completion/saving/reloading."""
1797
1797
1798 if self.readline_use:
1798 if self.readline_use:
1799 import IPython.utils.rlineimpl as readline
1799 import IPython.utils.rlineimpl as readline
1800
1800
1801 self.rl_next_input = None
1801 self.rl_next_input = None
1802 self.rl_do_indent = False
1802 self.rl_do_indent = False
1803
1803
1804 if not self.readline_use or not readline.have_readline:
1804 if not self.readline_use or not readline.have_readline:
1805 self.has_readline = False
1805 self.has_readline = False
1806 self.readline = None
1806 self.readline = None
1807 # Set a number of methods that depend on readline to be no-op
1807 # Set a number of methods that depend on readline to be no-op
1808 self.readline_no_record = no_op_context
1808 self.readline_no_record = no_op_context
1809 self.set_readline_completer = no_op
1809 self.set_readline_completer = no_op
1810 self.set_custom_completer = no_op
1810 self.set_custom_completer = no_op
1811 if self.readline_use:
1811 if self.readline_use:
1812 warn('Readline services not available or not loaded.')
1812 warn('Readline services not available or not loaded.')
1813 else:
1813 else:
1814 self.has_readline = True
1814 self.has_readline = True
1815 self.readline = readline
1815 self.readline = readline
1816 sys.modules['readline'] = readline
1816 sys.modules['readline'] = readline
1817
1817
1818 # Platform-specific configuration
1818 # Platform-specific configuration
1819 if os.name == 'nt':
1819 if os.name == 'nt':
1820 # FIXME - check with Frederick to see if we can harmonize
1820 # FIXME - check with Frederick to see if we can harmonize
1821 # naming conventions with pyreadline to avoid this
1821 # naming conventions with pyreadline to avoid this
1822 # platform-dependent check
1822 # platform-dependent check
1823 self.readline_startup_hook = readline.set_pre_input_hook
1823 self.readline_startup_hook = readline.set_pre_input_hook
1824 else:
1824 else:
1825 self.readline_startup_hook = readline.set_startup_hook
1825 self.readline_startup_hook = readline.set_startup_hook
1826
1826
1827 # Load user's initrc file (readline config)
1827 # Load user's initrc file (readline config)
1828 # Or if libedit is used, load editrc.
1828 # Or if libedit is used, load editrc.
1829 inputrc_name = os.environ.get('INPUTRC')
1829 inputrc_name = os.environ.get('INPUTRC')
1830 if inputrc_name is None:
1830 if inputrc_name is None:
1831 inputrc_name = '.inputrc'
1831 inputrc_name = '.inputrc'
1832 if readline.uses_libedit:
1832 if readline.uses_libedit:
1833 inputrc_name = '.editrc'
1833 inputrc_name = '.editrc'
1834 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1834 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1835 if os.path.isfile(inputrc_name):
1835 if os.path.isfile(inputrc_name):
1836 try:
1836 try:
1837 readline.read_init_file(inputrc_name)
1837 readline.read_init_file(inputrc_name)
1838 except:
1838 except:
1839 warn('Problems reading readline initialization file <%s>'
1839 warn('Problems reading readline initialization file <%s>'
1840 % inputrc_name)
1840 % inputrc_name)
1841
1841
1842 # Configure readline according to user's prefs
1842 # Configure readline according to user's prefs
1843 # This is only done if GNU readline is being used. If libedit
1843 # This is only done if GNU readline is being used. If libedit
1844 # is being used (as on Leopard) the readline config is
1844 # is being used (as on Leopard) the readline config is
1845 # not run as the syntax for libedit is different.
1845 # not run as the syntax for libedit is different.
1846 if not readline.uses_libedit:
1846 if not readline.uses_libedit:
1847 for rlcommand in self.readline_parse_and_bind:
1847 for rlcommand in self.readline_parse_and_bind:
1848 #print "loading rl:",rlcommand # dbg
1848 #print "loading rl:",rlcommand # dbg
1849 readline.parse_and_bind(rlcommand)
1849 readline.parse_and_bind(rlcommand)
1850
1850
1851 # Remove some chars from the delimiters list. If we encounter
1851 # Remove some chars from the delimiters list. If we encounter
1852 # unicode chars, discard them.
1852 # unicode chars, discard them.
1853 delims = readline.get_completer_delims()
1853 delims = readline.get_completer_delims()
1854 if not py3compat.PY3:
1854 if not py3compat.PY3:
1855 delims = delims.encode("ascii", "ignore")
1855 delims = delims.encode("ascii", "ignore")
1856 for d in self.readline_remove_delims:
1856 for d in self.readline_remove_delims:
1857 delims = delims.replace(d, "")
1857 delims = delims.replace(d, "")
1858 delims = delims.replace(ESC_MAGIC, '')
1858 delims = delims.replace(ESC_MAGIC, '')
1859 readline.set_completer_delims(delims)
1859 readline.set_completer_delims(delims)
1860 # Store these so we can restore them if something like rpy2 modifies
1860 # Store these so we can restore them if something like rpy2 modifies
1861 # them.
1861 # them.
1862 self.readline_delims = delims
1862 self.readline_delims = delims
1863 # otherwise we end up with a monster history after a while:
1863 # otherwise we end up with a monster history after a while:
1864 readline.set_history_length(self.history_length)
1864 readline.set_history_length(self.history_length)
1865
1865
1866 self.refill_readline_hist()
1866 self.refill_readline_hist()
1867 self.readline_no_record = ReadlineNoRecord(self)
1867 self.readline_no_record = ReadlineNoRecord(self)
1868
1868
1869 # Configure auto-indent for all platforms
1869 # Configure auto-indent for all platforms
1870 self.set_autoindent(self.autoindent)
1870 self.set_autoindent(self.autoindent)
1871
1871
1872 def refill_readline_hist(self):
1872 def refill_readline_hist(self):
1873 # Load the last 1000 lines from history
1873 # Load the last 1000 lines from history
1874 self.readline.clear_history()
1874 self.readline.clear_history()
1875 stdin_encoding = sys.stdin.encoding or "utf-8"
1875 stdin_encoding = sys.stdin.encoding or "utf-8"
1876 last_cell = u""
1876 last_cell = u""
1877 for _, _, cell in self.history_manager.get_tail(1000,
1877 for _, _, cell in self.history_manager.get_tail(1000,
1878 include_latest=True):
1878 include_latest=True):
1879 # Ignore blank lines and consecutive duplicates
1879 # Ignore blank lines and consecutive duplicates
1880 cell = cell.rstrip()
1880 cell = cell.rstrip()
1881 if cell and (cell != last_cell):
1881 if cell and (cell != last_cell):
1882 try:
1882 try:
1883 if self.multiline_history:
1883 if self.multiline_history:
1884 self.readline.add_history(py3compat.unicode_to_str(cell,
1884 self.readline.add_history(py3compat.unicode_to_str(cell,
1885 stdin_encoding))
1885 stdin_encoding))
1886 else:
1886 else:
1887 for line in cell.splitlines():
1887 for line in cell.splitlines():
1888 self.readline.add_history(py3compat.unicode_to_str(line,
1888 self.readline.add_history(py3compat.unicode_to_str(line,
1889 stdin_encoding))
1889 stdin_encoding))
1890 last_cell = cell
1890 last_cell = cell
1891
1891
1892 except TypeError:
1892 except TypeError:
1893 # The history DB can get corrupted so it returns strings
1893 # The history DB can get corrupted so it returns strings
1894 # containing null bytes, which readline objects to.
1894 # containing null bytes, which readline objects to.
1895 continue
1895 continue
1896
1896
1897 @skip_doctest
1897 @skip_doctest
1898 def set_next_input(self, s):
1898 def set_next_input(self, s):
1899 """ Sets the 'default' input string for the next command line.
1899 """ Sets the 'default' input string for the next command line.
1900
1900
1901 Requires readline.
1901 Requires readline.
1902
1902
1903 Example::
1903 Example::
1904
1904
1905 In [1]: _ip.set_next_input("Hello Word")
1905 In [1]: _ip.set_next_input("Hello Word")
1906 In [2]: Hello Word_ # cursor is here
1906 In [2]: Hello Word_ # cursor is here
1907 """
1907 """
1908 self.rl_next_input = py3compat.cast_bytes_py2(s)
1908 self.rl_next_input = py3compat.cast_bytes_py2(s)
1909
1909
1910 # Maybe move this to the terminal subclass?
1910 # Maybe move this to the terminal subclass?
1911 def pre_readline(self):
1911 def pre_readline(self):
1912 """readline hook to be used at the start of each line.
1912 """readline hook to be used at the start of each line.
1913
1913
1914 Currently it handles auto-indent only."""
1914 Currently it handles auto-indent only."""
1915
1915
1916 if self.rl_do_indent:
1916 if self.rl_do_indent:
1917 self.readline.insert_text(self._indent_current_str())
1917 self.readline.insert_text(self._indent_current_str())
1918 if self.rl_next_input is not None:
1918 if self.rl_next_input is not None:
1919 self.readline.insert_text(self.rl_next_input)
1919 self.readline.insert_text(self.rl_next_input)
1920 self.rl_next_input = None
1920 self.rl_next_input = None
1921
1921
1922 def _indent_current_str(self):
1922 def _indent_current_str(self):
1923 """return the current level of indentation as a string"""
1923 """return the current level of indentation as a string"""
1924 return self.input_splitter.indent_spaces * ' '
1924 return self.input_splitter.indent_spaces * ' '
1925
1925
1926 #-------------------------------------------------------------------------
1926 #-------------------------------------------------------------------------
1927 # Things related to text completion
1927 # Things related to text completion
1928 #-------------------------------------------------------------------------
1928 #-------------------------------------------------------------------------
1929
1929
1930 def init_completer(self):
1930 def init_completer(self):
1931 """Initialize the completion machinery.
1931 """Initialize the completion machinery.
1932
1932
1933 This creates completion machinery that can be used by client code,
1933 This creates completion machinery that can be used by client code,
1934 either interactively in-process (typically triggered by the readline
1934 either interactively in-process (typically triggered by the readline
1935 library), programatically (such as in test suites) or out-of-prcess
1935 library), programatically (such as in test suites) or out-of-prcess
1936 (typically over the network by remote frontends).
1936 (typically over the network by remote frontends).
1937 """
1937 """
1938 from IPython.core.completer import IPCompleter
1938 from IPython.core.completer import IPCompleter
1939 from IPython.core.completerlib import (module_completer,
1939 from IPython.core.completerlib import (module_completer,
1940 magic_run_completer, cd_completer, reset_completer)
1940 magic_run_completer, cd_completer, reset_completer)
1941
1941
1942 self.Completer = IPCompleter(shell=self,
1942 self.Completer = IPCompleter(shell=self,
1943 namespace=self.user_ns,
1943 namespace=self.user_ns,
1944 global_namespace=self.user_global_ns,
1944 global_namespace=self.user_global_ns,
1945 use_readline=self.has_readline,
1945 use_readline=self.has_readline,
1946 parent=self,
1946 parent=self,
1947 )
1947 )
1948 self.configurables.append(self.Completer)
1948 self.configurables.append(self.Completer)
1949
1949
1950 # Add custom completers to the basic ones built into IPCompleter
1950 # Add custom completers to the basic ones built into IPCompleter
1951 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1951 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1952 self.strdispatchers['complete_command'] = sdisp
1952 self.strdispatchers['complete_command'] = sdisp
1953 self.Completer.custom_completers = sdisp
1953 self.Completer.custom_completers = sdisp
1954
1954
1955 self.set_hook('complete_command', module_completer, str_key = 'import')
1955 self.set_hook('complete_command', module_completer, str_key = 'import')
1956 self.set_hook('complete_command', module_completer, str_key = 'from')
1956 self.set_hook('complete_command', module_completer, str_key = 'from')
1957 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1957 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1958 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1958 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1959 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1959 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1960
1960
1961 # Only configure readline if we truly are using readline. IPython can
1961 # Only configure readline if we truly are using readline. IPython can
1962 # do tab-completion over the network, in GUIs, etc, where readline
1962 # do tab-completion over the network, in GUIs, etc, where readline
1963 # itself may be absent
1963 # itself may be absent
1964 if self.has_readline:
1964 if self.has_readline:
1965 self.set_readline_completer()
1965 self.set_readline_completer()
1966
1966
1967 def complete(self, text, line=None, cursor_pos=None):
1967 def complete(self, text, line=None, cursor_pos=None):
1968 """Return the completed text and a list of completions.
1968 """Return the completed text and a list of completions.
1969
1969
1970 Parameters
1970 Parameters
1971 ----------
1971 ----------
1972
1972
1973 text : string
1973 text : string
1974 A string of text to be completed on. It can be given as empty and
1974 A string of text to be completed on. It can be given as empty and
1975 instead a line/position pair are given. In this case, the
1975 instead a line/position pair are given. In this case, the
1976 completer itself will split the line like readline does.
1976 completer itself will split the line like readline does.
1977
1977
1978 line : string, optional
1978 line : string, optional
1979 The complete line that text is part of.
1979 The complete line that text is part of.
1980
1980
1981 cursor_pos : int, optional
1981 cursor_pos : int, optional
1982 The position of the cursor on the input line.
1982 The position of the cursor on the input line.
1983
1983
1984 Returns
1984 Returns
1985 -------
1985 -------
1986 text : string
1986 text : string
1987 The actual text that was completed.
1987 The actual text that was completed.
1988
1988
1989 matches : list
1989 matches : list
1990 A sorted list with all possible completions.
1990 A sorted list with all possible completions.
1991
1991
1992 The optional arguments allow the completion to take more context into
1992 The optional arguments allow the completion to take more context into
1993 account, and are part of the low-level completion API.
1993 account, and are part of the low-level completion API.
1994
1994
1995 This is a wrapper around the completion mechanism, similar to what
1995 This is a wrapper around the completion mechanism, similar to what
1996 readline does at the command line when the TAB key is hit. By
1996 readline does at the command line when the TAB key is hit. By
1997 exposing it as a method, it can be used by other non-readline
1997 exposing it as a method, it can be used by other non-readline
1998 environments (such as GUIs) for text completion.
1998 environments (such as GUIs) for text completion.
1999
1999
2000 Simple usage example:
2000 Simple usage example:
2001
2001
2002 In [1]: x = 'hello'
2002 In [1]: x = 'hello'
2003
2003
2004 In [2]: _ip.complete('x.l')
2004 In [2]: _ip.complete('x.l')
2005 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2005 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2006 """
2006 """
2007
2007
2008 # Inject names into __builtin__ so we can complete on the added names.
2008 # Inject names into __builtin__ so we can complete on the added names.
2009 with self.builtin_trap:
2009 with self.builtin_trap:
2010 return self.Completer.complete(text, line, cursor_pos)
2010 return self.Completer.complete(text, line, cursor_pos)
2011
2011
2012 def set_custom_completer(self, completer, pos=0):
2012 def set_custom_completer(self, completer, pos=0):
2013 """Adds a new custom completer function.
2013 """Adds a new custom completer function.
2014
2014
2015 The position argument (defaults to 0) is the index in the completers
2015 The position argument (defaults to 0) is the index in the completers
2016 list where you want the completer to be inserted."""
2016 list where you want the completer to be inserted."""
2017
2017
2018 newcomp = types.MethodType(completer,self.Completer)
2018 newcomp = types.MethodType(completer,self.Completer)
2019 self.Completer.matchers.insert(pos,newcomp)
2019 self.Completer.matchers.insert(pos,newcomp)
2020
2020
2021 def set_readline_completer(self):
2021 def set_readline_completer(self):
2022 """Reset readline's completer to be our own."""
2022 """Reset readline's completer to be our own."""
2023 self.readline.set_completer(self.Completer.rlcomplete)
2023 self.readline.set_completer(self.Completer.rlcomplete)
2024
2024
2025 def set_completer_frame(self, frame=None):
2025 def set_completer_frame(self, frame=None):
2026 """Set the frame of the completer."""
2026 """Set the frame of the completer."""
2027 if frame:
2027 if frame:
2028 self.Completer.namespace = frame.f_locals
2028 self.Completer.namespace = frame.f_locals
2029 self.Completer.global_namespace = frame.f_globals
2029 self.Completer.global_namespace = frame.f_globals
2030 else:
2030 else:
2031 self.Completer.namespace = self.user_ns
2031 self.Completer.namespace = self.user_ns
2032 self.Completer.global_namespace = self.user_global_ns
2032 self.Completer.global_namespace = self.user_global_ns
2033
2033
2034 #-------------------------------------------------------------------------
2034 #-------------------------------------------------------------------------
2035 # Things related to magics
2035 # Things related to magics
2036 #-------------------------------------------------------------------------
2036 #-------------------------------------------------------------------------
2037
2037
2038 def init_magics(self):
2038 def init_magics(self):
2039 from IPython.core import magics as m
2039 from IPython.core import magics as m
2040 self.magics_manager = magic.MagicsManager(shell=self,
2040 self.magics_manager = magic.MagicsManager(shell=self,
2041 parent=self,
2041 parent=self,
2042 user_magics=m.UserMagics(self))
2042 user_magics=m.UserMagics(self))
2043 self.configurables.append(self.magics_manager)
2043 self.configurables.append(self.magics_manager)
2044
2044
2045 # Expose as public API from the magics manager
2045 # Expose as public API from the magics manager
2046 self.register_magics = self.magics_manager.register
2046 self.register_magics = self.magics_manager.register
2047 self.define_magic = self.magics_manager.define_magic
2047 self.define_magic = self.magics_manager.define_magic
2048
2048
2049 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2049 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2050 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2050 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2051 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2051 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2052 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2052 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2053 )
2053 )
2054
2054
2055 # Register Magic Aliases
2055 # Register Magic Aliases
2056 mman = self.magics_manager
2056 mman = self.magics_manager
2057 # FIXME: magic aliases should be defined by the Magics classes
2057 # FIXME: magic aliases should be defined by the Magics classes
2058 # or in MagicsManager, not here
2058 # or in MagicsManager, not here
2059 mman.register_alias('ed', 'edit')
2059 mman.register_alias('ed', 'edit')
2060 mman.register_alias('hist', 'history')
2060 mman.register_alias('hist', 'history')
2061 mman.register_alias('rep', 'recall')
2061 mman.register_alias('rep', 'recall')
2062 mman.register_alias('SVG', 'svg', 'cell')
2062 mman.register_alias('SVG', 'svg', 'cell')
2063 mman.register_alias('HTML', 'html', 'cell')
2063 mman.register_alias('HTML', 'html', 'cell')
2064 mman.register_alias('file', 'writefile', 'cell')
2064 mman.register_alias('file', 'writefile', 'cell')
2065
2065
2066 # FIXME: Move the color initialization to the DisplayHook, which
2066 # FIXME: Move the color initialization to the DisplayHook, which
2067 # should be split into a prompt manager and displayhook. We probably
2067 # should be split into a prompt manager and displayhook. We probably
2068 # even need a centralize colors management object.
2068 # even need a centralize colors management object.
2069 self.magic('colors %s' % self.colors)
2069 self.magic('colors %s' % self.colors)
2070
2070
2071 # Defined here so that it's included in the documentation
2071 # Defined here so that it's included in the documentation
2072 @functools.wraps(magic.MagicsManager.register_function)
2072 @functools.wraps(magic.MagicsManager.register_function)
2073 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2073 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2074 self.magics_manager.register_function(func,
2074 self.magics_manager.register_function(func,
2075 magic_kind=magic_kind, magic_name=magic_name)
2075 magic_kind=magic_kind, magic_name=magic_name)
2076
2076
2077 def run_line_magic(self, magic_name, line):
2077 def run_line_magic(self, magic_name, line):
2078 """Execute the given line magic.
2078 """Execute the given line magic.
2079
2079
2080 Parameters
2080 Parameters
2081 ----------
2081 ----------
2082 magic_name : str
2082 magic_name : str
2083 Name of the desired magic function, without '%' prefix.
2083 Name of the desired magic function, without '%' prefix.
2084
2084
2085 line : str
2085 line : str
2086 The rest of the input line as a single string.
2086 The rest of the input line as a single string.
2087 """
2087 """
2088 fn = self.find_line_magic(magic_name)
2088 fn = self.find_line_magic(magic_name)
2089 if fn is None:
2089 if fn is None:
2090 cm = self.find_cell_magic(magic_name)
2090 cm = self.find_cell_magic(magic_name)
2091 etpl = "Line magic function `%%%s` not found%s."
2091 etpl = "Line magic function `%%%s` not found%s."
2092 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2092 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2093 'did you mean that instead?)' % magic_name )
2093 'did you mean that instead?)' % magic_name )
2094 error(etpl % (magic_name, extra))
2094 error(etpl % (magic_name, extra))
2095 else:
2095 else:
2096 # Note: this is the distance in the stack to the user's frame.
2096 # Note: this is the distance in the stack to the user's frame.
2097 # This will need to be updated if the internal calling logic gets
2097 # This will need to be updated if the internal calling logic gets
2098 # refactored, or else we'll be expanding the wrong variables.
2098 # refactored, or else we'll be expanding the wrong variables.
2099 stack_depth = 2
2099 stack_depth = 2
2100 magic_arg_s = self.var_expand(line, stack_depth)
2100 magic_arg_s = self.var_expand(line, stack_depth)
2101 # Put magic args in a list so we can call with f(*a) syntax
2101 # Put magic args in a list so we can call with f(*a) syntax
2102 args = [magic_arg_s]
2102 args = [magic_arg_s]
2103 kwargs = {}
2103 kwargs = {}
2104 # Grab local namespace if we need it:
2104 # Grab local namespace if we need it:
2105 if getattr(fn, "needs_local_scope", False):
2105 if getattr(fn, "needs_local_scope", False):
2106 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2106 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2107 with self.builtin_trap:
2107 with self.builtin_trap:
2108 result = fn(*args,**kwargs)
2108 result = fn(*args,**kwargs)
2109 return result
2109 return result
2110
2110
2111 def run_cell_magic(self, magic_name, line, cell):
2111 def run_cell_magic(self, magic_name, line, cell):
2112 """Execute the given cell magic.
2112 """Execute the given cell magic.
2113
2113
2114 Parameters
2114 Parameters
2115 ----------
2115 ----------
2116 magic_name : str
2116 magic_name : str
2117 Name of the desired magic function, without '%' prefix.
2117 Name of the desired magic function, without '%' prefix.
2118
2118
2119 line : str
2119 line : str
2120 The rest of the first input line as a single string.
2120 The rest of the first input line as a single string.
2121
2121
2122 cell : str
2122 cell : str
2123 The body of the cell as a (possibly multiline) string.
2123 The body of the cell as a (possibly multiline) string.
2124 """
2124 """
2125 fn = self.find_cell_magic(magic_name)
2125 fn = self.find_cell_magic(magic_name)
2126 if fn is None:
2126 if fn is None:
2127 lm = self.find_line_magic(magic_name)
2127 lm = self.find_line_magic(magic_name)
2128 etpl = "Cell magic `%%{0}` not found{1}."
2128 etpl = "Cell magic `%%{0}` not found{1}."
2129 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2129 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2130 'did you mean that instead?)'.format(magic_name))
2130 'did you mean that instead?)'.format(magic_name))
2131 error(etpl.format(magic_name, extra))
2131 error(etpl.format(magic_name, extra))
2132 elif cell == '':
2132 elif cell == '':
2133 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2133 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2134 if self.find_line_magic(magic_name) is not None:
2134 if self.find_line_magic(magic_name) is not None:
2135 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2135 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2136 raise UsageError(message)
2136 raise UsageError(message)
2137 else:
2137 else:
2138 # Note: this is the distance in the stack to the user's frame.
2138 # Note: this is the distance in the stack to the user's frame.
2139 # This will need to be updated if the internal calling logic gets
2139 # This will need to be updated if the internal calling logic gets
2140 # refactored, or else we'll be expanding the wrong variables.
2140 # refactored, or else we'll be expanding the wrong variables.
2141 stack_depth = 2
2141 stack_depth = 2
2142 magic_arg_s = self.var_expand(line, stack_depth)
2142 magic_arg_s = self.var_expand(line, stack_depth)
2143 with self.builtin_trap:
2143 with self.builtin_trap:
2144 result = fn(magic_arg_s, cell)
2144 result = fn(magic_arg_s, cell)
2145 return result
2145 return result
2146
2146
2147 def find_line_magic(self, magic_name):
2147 def find_line_magic(self, magic_name):
2148 """Find and return a line magic by name.
2148 """Find and return a line magic by name.
2149
2149
2150 Returns None if the magic isn't found."""
2150 Returns None if the magic isn't found."""
2151 return self.magics_manager.magics['line'].get(magic_name)
2151 return self.magics_manager.magics['line'].get(magic_name)
2152
2152
2153 def find_cell_magic(self, magic_name):
2153 def find_cell_magic(self, magic_name):
2154 """Find and return a cell magic by name.
2154 """Find and return a cell magic by name.
2155
2155
2156 Returns None if the magic isn't found."""
2156 Returns None if the magic isn't found."""
2157 return self.magics_manager.magics['cell'].get(magic_name)
2157 return self.magics_manager.magics['cell'].get(magic_name)
2158
2158
2159 def find_magic(self, magic_name, magic_kind='line'):
2159 def find_magic(self, magic_name, magic_kind='line'):
2160 """Find and return a magic of the given type by name.
2160 """Find and return a magic of the given type by name.
2161
2161
2162 Returns None if the magic isn't found."""
2162 Returns None if the magic isn't found."""
2163 return self.magics_manager.magics[magic_kind].get(magic_name)
2163 return self.magics_manager.magics[magic_kind].get(magic_name)
2164
2164
2165 def magic(self, arg_s):
2165 def magic(self, arg_s):
2166 """DEPRECATED. Use run_line_magic() instead.
2166 """DEPRECATED. Use run_line_magic() instead.
2167
2167
2168 Call a magic function by name.
2168 Call a magic function by name.
2169
2169
2170 Input: a string containing the name of the magic function to call and
2170 Input: a string containing the name of the magic function to call and
2171 any additional arguments to be passed to the magic.
2171 any additional arguments to be passed to the magic.
2172
2172
2173 magic('name -opt foo bar') is equivalent to typing at the ipython
2173 magic('name -opt foo bar') is equivalent to typing at the ipython
2174 prompt:
2174 prompt:
2175
2175
2176 In[1]: %name -opt foo bar
2176 In[1]: %name -opt foo bar
2177
2177
2178 To call a magic without arguments, simply use magic('name').
2178 To call a magic without arguments, simply use magic('name').
2179
2179
2180 This provides a proper Python function to call IPython's magics in any
2180 This provides a proper Python function to call IPython's magics in any
2181 valid Python code you can type at the interpreter, including loops and
2181 valid Python code you can type at the interpreter, including loops and
2182 compound statements.
2182 compound statements.
2183 """
2183 """
2184 # TODO: should we issue a loud deprecation warning here?
2184 # TODO: should we issue a loud deprecation warning here?
2185 magic_name, _, magic_arg_s = arg_s.partition(' ')
2185 magic_name, _, magic_arg_s = arg_s.partition(' ')
2186 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2186 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2187 return self.run_line_magic(magic_name, magic_arg_s)
2187 return self.run_line_magic(magic_name, magic_arg_s)
2188
2188
2189 #-------------------------------------------------------------------------
2189 #-------------------------------------------------------------------------
2190 # Things related to macros
2190 # Things related to macros
2191 #-------------------------------------------------------------------------
2191 #-------------------------------------------------------------------------
2192
2192
2193 def define_macro(self, name, themacro):
2193 def define_macro(self, name, themacro):
2194 """Define a new macro
2194 """Define a new macro
2195
2195
2196 Parameters
2196 Parameters
2197 ----------
2197 ----------
2198 name : str
2198 name : str
2199 The name of the macro.
2199 The name of the macro.
2200 themacro : str or Macro
2200 themacro : str or Macro
2201 The action to do upon invoking the macro. If a string, a new
2201 The action to do upon invoking the macro. If a string, a new
2202 Macro object is created by passing the string to it.
2202 Macro object is created by passing the string to it.
2203 """
2203 """
2204
2204
2205 from IPython.core import macro
2205 from IPython.core import macro
2206
2206
2207 if isinstance(themacro, string_types):
2207 if isinstance(themacro, string_types):
2208 themacro = macro.Macro(themacro)
2208 themacro = macro.Macro(themacro)
2209 if not isinstance(themacro, macro.Macro):
2209 if not isinstance(themacro, macro.Macro):
2210 raise ValueError('A macro must be a string or a Macro instance.')
2210 raise ValueError('A macro must be a string or a Macro instance.')
2211 self.user_ns[name] = themacro
2211 self.user_ns[name] = themacro
2212
2212
2213 #-------------------------------------------------------------------------
2213 #-------------------------------------------------------------------------
2214 # Things related to the running of system commands
2214 # Things related to the running of system commands
2215 #-------------------------------------------------------------------------
2215 #-------------------------------------------------------------------------
2216
2216
2217 def system_piped(self, cmd):
2217 def system_piped(self, cmd):
2218 """Call the given cmd in a subprocess, piping stdout/err
2218 """Call the given cmd in a subprocess, piping stdout/err
2219
2219
2220 Parameters
2220 Parameters
2221 ----------
2221 ----------
2222 cmd : str
2222 cmd : str
2223 Command to execute (can not end in '&', as background processes are
2223 Command to execute (can not end in '&', as background processes are
2224 not supported. Should not be a command that expects input
2224 not supported. Should not be a command that expects input
2225 other than simple text.
2225 other than simple text.
2226 """
2226 """
2227 if cmd.rstrip().endswith('&'):
2227 if cmd.rstrip().endswith('&'):
2228 # this is *far* from a rigorous test
2228 # this is *far* from a rigorous test
2229 # We do not support backgrounding processes because we either use
2229 # We do not support backgrounding processes because we either use
2230 # pexpect or pipes to read from. Users can always just call
2230 # pexpect or pipes to read from. Users can always just call
2231 # os.system() or use ip.system=ip.system_raw
2231 # os.system() or use ip.system=ip.system_raw
2232 # if they really want a background process.
2232 # if they really want a background process.
2233 raise OSError("Background processes not supported.")
2233 raise OSError("Background processes not supported.")
2234
2234
2235 # we explicitly do NOT return the subprocess status code, because
2235 # we explicitly do NOT return the subprocess status code, because
2236 # a non-None value would trigger :func:`sys.displayhook` calls.
2236 # a non-None value would trigger :func:`sys.displayhook` calls.
2237 # Instead, we store the exit_code in user_ns.
2237 # Instead, we store the exit_code in user_ns.
2238 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2238 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2239
2239
2240 def system_raw(self, cmd):
2240 def system_raw(self, cmd):
2241 """Call the given cmd in a subprocess using os.system on Windows or
2241 """Call the given cmd in a subprocess using os.system on Windows or
2242 subprocess.call using the system shell on other platforms.
2242 subprocess.call using the system shell on other platforms.
2243
2243
2244 Parameters
2244 Parameters
2245 ----------
2245 ----------
2246 cmd : str
2246 cmd : str
2247 Command to execute.
2247 Command to execute.
2248 """
2248 """
2249 cmd = self.var_expand(cmd, depth=1)
2249 cmd = self.var_expand(cmd, depth=1)
2250 # protect os.system from UNC paths on Windows, which it can't handle:
2250 # protect os.system from UNC paths on Windows, which it can't handle:
2251 if sys.platform == 'win32':
2251 if sys.platform == 'win32':
2252 from IPython.utils._process_win32 import AvoidUNCPath
2252 from IPython.utils._process_win32 import AvoidUNCPath
2253 with AvoidUNCPath() as path:
2253 with AvoidUNCPath() as path:
2254 if path is not None:
2254 if path is not None:
2255 cmd = '"pushd %s &&"%s' % (path, cmd)
2255 cmd = '"pushd %s &&"%s' % (path, cmd)
2256 cmd = py3compat.unicode_to_str(cmd)
2256 cmd = py3compat.unicode_to_str(cmd)
2257 ec = os.system(cmd)
2257 ec = os.system(cmd)
2258 else:
2258 else:
2259 cmd = py3compat.unicode_to_str(cmd)
2259 cmd = py3compat.unicode_to_str(cmd)
2260 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2260 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2261 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2261 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2262 # exit code is positive for program failure, or negative for
2262 # exit code is positive for program failure, or negative for
2263 # terminating signal number.
2263 # terminating signal number.
2264
2264
2265 # We explicitly do NOT return the subprocess status code, because
2265 # We explicitly do NOT return the subprocess status code, because
2266 # a non-None value would trigger :func:`sys.displayhook` calls.
2266 # a non-None value would trigger :func:`sys.displayhook` calls.
2267 # Instead, we store the exit_code in user_ns.
2267 # Instead, we store the exit_code in user_ns.
2268 self.user_ns['_exit_code'] = ec
2268 self.user_ns['_exit_code'] = ec
2269
2269
2270 # use piped system by default, because it is better behaved
2270 # use piped system by default, because it is better behaved
2271 system = system_piped
2271 system = system_piped
2272
2272
2273 def getoutput(self, cmd, split=True, depth=0):
2273 def getoutput(self, cmd, split=True, depth=0):
2274 """Get output (possibly including stderr) from a subprocess.
2274 """Get output (possibly including stderr) from a subprocess.
2275
2275
2276 Parameters
2276 Parameters
2277 ----------
2277 ----------
2278 cmd : str
2278 cmd : str
2279 Command to execute (can not end in '&', as background processes are
2279 Command to execute (can not end in '&', as background processes are
2280 not supported.
2280 not supported.
2281 split : bool, optional
2281 split : bool, optional
2282 If True, split the output into an IPython SList. Otherwise, an
2282 If True, split the output into an IPython SList. Otherwise, an
2283 IPython LSString is returned. These are objects similar to normal
2283 IPython LSString is returned. These are objects similar to normal
2284 lists and strings, with a few convenience attributes for easier
2284 lists and strings, with a few convenience attributes for easier
2285 manipulation of line-based output. You can use '?' on them for
2285 manipulation of line-based output. You can use '?' on them for
2286 details.
2286 details.
2287 depth : int, optional
2287 depth : int, optional
2288 How many frames above the caller are the local variables which should
2288 How many frames above the caller are the local variables which should
2289 be expanded in the command string? The default (0) assumes that the
2289 be expanded in the command string? The default (0) assumes that the
2290 expansion variables are in the stack frame calling this function.
2290 expansion variables are in the stack frame calling this function.
2291 """
2291 """
2292 if cmd.rstrip().endswith('&'):
2292 if cmd.rstrip().endswith('&'):
2293 # this is *far* from a rigorous test
2293 # this is *far* from a rigorous test
2294 raise OSError("Background processes not supported.")
2294 raise OSError("Background processes not supported.")
2295 out = getoutput(self.var_expand(cmd, depth=depth+1))
2295 out = getoutput(self.var_expand(cmd, depth=depth+1))
2296 if split:
2296 if split:
2297 out = SList(out.splitlines())
2297 out = SList(out.splitlines())
2298 else:
2298 else:
2299 out = LSString(out)
2299 out = LSString(out)
2300 return out
2300 return out
2301
2301
2302 #-------------------------------------------------------------------------
2302 #-------------------------------------------------------------------------
2303 # Things related to aliases
2303 # Things related to aliases
2304 #-------------------------------------------------------------------------
2304 #-------------------------------------------------------------------------
2305
2305
2306 def init_alias(self):
2306 def init_alias(self):
2307 self.alias_manager = AliasManager(shell=self, parent=self)
2307 self.alias_manager = AliasManager(shell=self, parent=self)
2308 self.configurables.append(self.alias_manager)
2308 self.configurables.append(self.alias_manager)
2309
2309
2310 #-------------------------------------------------------------------------
2310 #-------------------------------------------------------------------------
2311 # Things related to extensions
2311 # Things related to extensions
2312 #-------------------------------------------------------------------------
2312 #-------------------------------------------------------------------------
2313
2313
2314 def init_extension_manager(self):
2314 def init_extension_manager(self):
2315 self.extension_manager = ExtensionManager(shell=self, parent=self)
2315 self.extension_manager = ExtensionManager(shell=self, parent=self)
2316 self.configurables.append(self.extension_manager)
2316 self.configurables.append(self.extension_manager)
2317
2317
2318 #-------------------------------------------------------------------------
2318 #-------------------------------------------------------------------------
2319 # Things related to payloads
2319 # Things related to payloads
2320 #-------------------------------------------------------------------------
2320 #-------------------------------------------------------------------------
2321
2321
2322 def init_payload(self):
2322 def init_payload(self):
2323 self.payload_manager = PayloadManager(parent=self)
2323 self.payload_manager = PayloadManager(parent=self)
2324 self.configurables.append(self.payload_manager)
2324 self.configurables.append(self.payload_manager)
2325
2325
2326 #-------------------------------------------------------------------------
2326 #-------------------------------------------------------------------------
2327 # Things related to widgets
2327 # Things related to widgets
2328 #-------------------------------------------------------------------------
2328 #-------------------------------------------------------------------------
2329
2329
2330 def init_comms(self):
2330 def init_comms(self):
2331 # not implemented in the base class
2331 # not implemented in the base class
2332 pass
2332 pass
2333
2333
2334 #-------------------------------------------------------------------------
2334 #-------------------------------------------------------------------------
2335 # Things related to the prefilter
2335 # Things related to the prefilter
2336 #-------------------------------------------------------------------------
2336 #-------------------------------------------------------------------------
2337
2337
2338 def init_prefilter(self):
2338 def init_prefilter(self):
2339 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2339 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2340 self.configurables.append(self.prefilter_manager)
2340 self.configurables.append(self.prefilter_manager)
2341 # Ultimately this will be refactored in the new interpreter code, but
2341 # Ultimately this will be refactored in the new interpreter code, but
2342 # for now, we should expose the main prefilter method (there's legacy
2342 # for now, we should expose the main prefilter method (there's legacy
2343 # code out there that may rely on this).
2343 # code out there that may rely on this).
2344 self.prefilter = self.prefilter_manager.prefilter_lines
2344 self.prefilter = self.prefilter_manager.prefilter_lines
2345
2345
2346 def auto_rewrite_input(self, cmd):
2346 def auto_rewrite_input(self, cmd):
2347 """Print to the screen the rewritten form of the user's command.
2347 """Print to the screen the rewritten form of the user's command.
2348
2348
2349 This shows visual feedback by rewriting input lines that cause
2349 This shows visual feedback by rewriting input lines that cause
2350 automatic calling to kick in, like::
2350 automatic calling to kick in, like::
2351
2351
2352 /f x
2352 /f x
2353
2353
2354 into::
2354 into::
2355
2355
2356 ------> f(x)
2356 ------> f(x)
2357
2357
2358 after the user's input prompt. This helps the user understand that the
2358 after the user's input prompt. This helps the user understand that the
2359 input line was transformed automatically by IPython.
2359 input line was transformed automatically by IPython.
2360 """
2360 """
2361 if not self.show_rewritten_input:
2361 if not self.show_rewritten_input:
2362 return
2362 return
2363
2363
2364 rw = self.prompt_manager.render('rewrite') + cmd
2364 rw = self.prompt_manager.render('rewrite') + cmd
2365
2365
2366 try:
2366 try:
2367 # plain ascii works better w/ pyreadline, on some machines, so
2367 # plain ascii works better w/ pyreadline, on some machines, so
2368 # we use it and only print uncolored rewrite if we have unicode
2368 # we use it and only print uncolored rewrite if we have unicode
2369 rw = str(rw)
2369 rw = str(rw)
2370 print(rw, file=io.stdout)
2370 print(rw, file=io.stdout)
2371 except UnicodeEncodeError:
2371 except UnicodeEncodeError:
2372 print("------> " + cmd)
2372 print("------> " + cmd)
2373
2373
2374 #-------------------------------------------------------------------------
2374 #-------------------------------------------------------------------------
2375 # Things related to extracting values/expressions from kernel and user_ns
2375 # Things related to extracting values/expressions from kernel and user_ns
2376 #-------------------------------------------------------------------------
2376 #-------------------------------------------------------------------------
2377
2377
2378 def _user_obj_error(self):
2378 def _user_obj_error(self):
2379 """return simple exception dict
2379 """return simple exception dict
2380
2380
2381 for use in user_variables / expressions
2381 for use in user_variables / expressions
2382 """
2382 """
2383
2383
2384 etype, evalue, tb = self._get_exc_info()
2384 etype, evalue, tb = self._get_exc_info()
2385 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2385 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2386
2386
2387 exc_info = {
2387 exc_info = {
2388 u'status' : 'error',
2388 u'status' : 'error',
2389 u'traceback' : stb,
2389 u'traceback' : stb,
2390 u'ename' : unicode_type(etype.__name__),
2390 u'ename' : unicode_type(etype.__name__),
2391 u'evalue' : py3compat.safe_unicode(evalue),
2391 u'evalue' : py3compat.safe_unicode(evalue),
2392 }
2392 }
2393
2393
2394 return exc_info
2394 return exc_info
2395
2395
2396 def _format_user_obj(self, obj):
2396 def _format_user_obj(self, obj):
2397 """format a user object to display dict
2397 """format a user object to display dict
2398
2398
2399 for use in user_expressions / variables
2399 for use in user_expressions / variables
2400 """
2400 """
2401
2401
2402 data, md = self.display_formatter.format(obj)
2402 data, md = self.display_formatter.format(obj)
2403 value = {
2403 value = {
2404 'status' : 'ok',
2404 'status' : 'ok',
2405 'data' : data,
2405 'data' : data,
2406 'metadata' : md,
2406 'metadata' : md,
2407 }
2407 }
2408 return value
2408 return value
2409
2409
2410 def user_variables(self, names):
2410 def user_variables(self, names):
2411 """Get a list of variable names from the user's namespace.
2411 """Get a list of variable names from the user's namespace.
2412
2412
2413 Parameters
2413 Parameters
2414 ----------
2414 ----------
2415 names : list of strings
2415 names : list of strings
2416 A list of names of variables to be read from the user namespace.
2416 A list of names of variables to be read from the user namespace.
2417
2417
2418 Returns
2418 Returns
2419 -------
2419 -------
2420 A dict, keyed by the input names and with the rich mime-type repr(s) of each value.
2420 A dict, keyed by the input names and with the rich mime-type repr(s) of each value.
2421 Each element will be a sub-dict of the same form as a display_data message.
2421 Each element will be a sub-dict of the same form as a display_data message.
2422 """
2422 """
2423 out = {}
2423 out = {}
2424 user_ns = self.user_ns
2424 user_ns = self.user_ns
2425
2425
2426 for varname in names:
2426 for varname in names:
2427 try:
2427 try:
2428 value = self._format_user_obj(user_ns[varname])
2428 value = self._format_user_obj(user_ns[varname])
2429 except:
2429 except:
2430 value = self._user_obj_error()
2430 value = self._user_obj_error()
2431 out[varname] = value
2431 out[varname] = value
2432 return out
2432 return out
2433
2433
2434 def user_expressions(self, expressions):
2434 def user_expressions(self, expressions):
2435 """Evaluate a dict of expressions in the user's namespace.
2435 """Evaluate a dict of expressions in the user's namespace.
2436
2436
2437 Parameters
2437 Parameters
2438 ----------
2438 ----------
2439 expressions : dict
2439 expressions : dict
2440 A dict with string keys and string values. The expression values
2440 A dict with string keys and string values. The expression values
2441 should be valid Python expressions, each of which will be evaluated
2441 should be valid Python expressions, each of which will be evaluated
2442 in the user namespace.
2442 in the user namespace.
2443
2443
2444 Returns
2444 Returns
2445 -------
2445 -------
2446 A dict, keyed like the input expressions dict, with the rich mime-typed
2446 A dict, keyed like the input expressions dict, with the rich mime-typed
2447 display_data of each value.
2447 display_data of each value.
2448 """
2448 """
2449 out = {}
2449 out = {}
2450 user_ns = self.user_ns
2450 user_ns = self.user_ns
2451 global_ns = self.user_global_ns
2451 global_ns = self.user_global_ns
2452
2452
2453 for key, expr in iteritems(expressions):
2453 for key, expr in iteritems(expressions):
2454 try:
2454 try:
2455 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2455 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2456 except:
2456 except:
2457 value = self._user_obj_error()
2457 value = self._user_obj_error()
2458 out[key] = value
2458 out[key] = value
2459 return out
2459 return out
2460
2460
2461 #-------------------------------------------------------------------------
2461 #-------------------------------------------------------------------------
2462 # Things related to the running of code
2462 # Things related to the running of code
2463 #-------------------------------------------------------------------------
2463 #-------------------------------------------------------------------------
2464
2464
2465 def ex(self, cmd):
2465 def ex(self, cmd):
2466 """Execute a normal python statement in user namespace."""
2466 """Execute a normal python statement in user namespace."""
2467 with self.builtin_trap:
2467 with self.builtin_trap:
2468 exec(cmd, self.user_global_ns, self.user_ns)
2468 exec(cmd, self.user_global_ns, self.user_ns)
2469
2469
2470 def ev(self, expr):
2470 def ev(self, expr):
2471 """Evaluate python expression expr in user namespace.
2471 """Evaluate python expression expr in user namespace.
2472
2472
2473 Returns the result of evaluation
2473 Returns the result of evaluation
2474 """
2474 """
2475 with self.builtin_trap:
2475 with self.builtin_trap:
2476 return eval(expr, self.user_global_ns, self.user_ns)
2476 return eval(expr, self.user_global_ns, self.user_ns)
2477
2477
2478 def safe_execfile(self, fname, *where, **kw):
2478 def safe_execfile(self, fname, *where, **kw):
2479 """A safe version of the builtin execfile().
2479 """A safe version of the builtin execfile().
2480
2480
2481 This version will never throw an exception, but instead print
2481 This version will never throw an exception, but instead print
2482 helpful error messages to the screen. This only works on pure
2482 helpful error messages to the screen. This only works on pure
2483 Python files with the .py extension.
2483 Python files with the .py extension.
2484
2484
2485 Parameters
2485 Parameters
2486 ----------
2486 ----------
2487 fname : string
2487 fname : string
2488 The name of the file to be executed.
2488 The name of the file to be executed.
2489 where : tuple
2489 where : tuple
2490 One or two namespaces, passed to execfile() as (globals,locals).
2490 One or two namespaces, passed to execfile() as (globals,locals).
2491 If only one is given, it is passed as both.
2491 If only one is given, it is passed as both.
2492 exit_ignore : bool (False)
2492 exit_ignore : bool (False)
2493 If True, then silence SystemExit for non-zero status (it is always
2493 If True, then silence SystemExit for non-zero status (it is always
2494 silenced for zero status, as it is so common).
2494 silenced for zero status, as it is so common).
2495 raise_exceptions : bool (False)
2495 raise_exceptions : bool (False)
2496 If True raise exceptions everywhere. Meant for testing.
2496 If True raise exceptions everywhere. Meant for testing.
2497
2497
2498 """
2498 """
2499 kw.setdefault('exit_ignore', False)
2499 kw.setdefault('exit_ignore', False)
2500 kw.setdefault('raise_exceptions', False)
2500 kw.setdefault('raise_exceptions', False)
2501
2501
2502 fname = os.path.abspath(os.path.expanduser(fname))
2502 fname = os.path.abspath(os.path.expanduser(fname))
2503
2503
2504 # Make sure we can open the file
2504 # Make sure we can open the file
2505 try:
2505 try:
2506 with open(fname) as thefile:
2506 with open(fname) as thefile:
2507 pass
2507 pass
2508 except:
2508 except:
2509 warn('Could not open file <%s> for safe execution.' % fname)
2509 warn('Could not open file <%s> for safe execution.' % fname)
2510 return
2510 return
2511
2511
2512 # Find things also in current directory. This is needed to mimic the
2512 # Find things also in current directory. This is needed to mimic the
2513 # behavior of running a script from the system command line, where
2513 # behavior of running a script from the system command line, where
2514 # Python inserts the script's directory into sys.path
2514 # Python inserts the script's directory into sys.path
2515 dname = os.path.dirname(fname)
2515 dname = os.path.dirname(fname)
2516
2516
2517 with prepended_to_syspath(dname):
2517 with prepended_to_syspath(dname):
2518 try:
2518 try:
2519 py3compat.execfile(fname,*where)
2519 py3compat.execfile(fname,*where)
2520 except SystemExit as status:
2520 except SystemExit as status:
2521 # If the call was made with 0 or None exit status (sys.exit(0)
2521 # If the call was made with 0 or None exit status (sys.exit(0)
2522 # or sys.exit() ), don't bother showing a traceback, as both of
2522 # or sys.exit() ), don't bother showing a traceback, as both of
2523 # these are considered normal by the OS:
2523 # these are considered normal by the OS:
2524 # > python -c'import sys;sys.exit(0)'; echo $?
2524 # > python -c'import sys;sys.exit(0)'; echo $?
2525 # 0
2525 # 0
2526 # > python -c'import sys;sys.exit()'; echo $?
2526 # > python -c'import sys;sys.exit()'; echo $?
2527 # 0
2527 # 0
2528 # For other exit status, we show the exception unless
2528 # For other exit status, we show the exception unless
2529 # explicitly silenced, but only in short form.
2529 # explicitly silenced, but only in short form.
2530 if kw['raise_exceptions']:
2530 if kw['raise_exceptions']:
2531 raise
2531 raise
2532 if status.code and not kw['exit_ignore']:
2532 if status.code and not kw['exit_ignore']:
2533 self.showtraceback(exception_only=True)
2533 self.showtraceback(exception_only=True)
2534 except:
2534 except:
2535 if kw['raise_exceptions']:
2535 if kw['raise_exceptions']:
2536 raise
2536 raise
2537 # tb offset is 2 because we wrap execfile
2537 # tb offset is 2 because we wrap execfile
2538 self.showtraceback(tb_offset=2)
2538 self.showtraceback(tb_offset=2)
2539
2539
2540 def safe_execfile_ipy(self, fname):
2540 def safe_execfile_ipy(self, fname):
2541 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2541 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2542
2542
2543 Parameters
2543 Parameters
2544 ----------
2544 ----------
2545 fname : str
2545 fname : str
2546 The name of the file to execute. The filename must have a
2546 The name of the file to execute. The filename must have a
2547 .ipy or .ipynb extension.
2547 .ipy or .ipynb extension.
2548 """
2548 """
2549 fname = os.path.abspath(os.path.expanduser(fname))
2549 fname = os.path.abspath(os.path.expanduser(fname))
2550
2550
2551 # Make sure we can open the file
2551 # Make sure we can open the file
2552 try:
2552 try:
2553 with open(fname) as thefile:
2553 with open(fname) as thefile:
2554 pass
2554 pass
2555 except:
2555 except:
2556 warn('Could not open file <%s> for safe execution.' % fname)
2556 warn('Could not open file <%s> for safe execution.' % fname)
2557 return
2557 return
2558
2558
2559 # Find things also in current directory. This is needed to mimic the
2559 # Find things also in current directory. This is needed to mimic the
2560 # behavior of running a script from the system command line, where
2560 # behavior of running a script from the system command line, where
2561 # Python inserts the script's directory into sys.path
2561 # Python inserts the script's directory into sys.path
2562 dname = os.path.dirname(fname)
2562 dname = os.path.dirname(fname)
2563
2563
2564 def get_cells():
2564 def get_cells():
2565 """generator for sequence of code blocks to run"""
2565 """generator for sequence of code blocks to run"""
2566 if fname.endswith('.ipynb'):
2566 if fname.endswith('.ipynb'):
2567 from IPython.nbformat import current
2567 from IPython.nbformat import current
2568 with open(fname) as f:
2568 with open(fname) as f:
2569 nb = current.read(f, 'json')
2569 nb = current.read(f, 'json')
2570 if not nb.worksheets:
2570 if not nb.worksheets:
2571 return
2571 return
2572 for cell in nb.worksheets[0].cells:
2572 for cell in nb.worksheets[0].cells:
2573 if cell.cell_type == 'code':
2573 if cell.cell_type == 'code':
2574 yield cell.input
2574 yield cell.input
2575 else:
2575 else:
2576 with open(fname) as f:
2576 with open(fname) as f:
2577 yield f.read()
2577 yield f.read()
2578
2578
2579 with prepended_to_syspath(dname):
2579 with prepended_to_syspath(dname):
2580 try:
2580 try:
2581 for cell in get_cells():
2581 for cell in get_cells():
2582 # self.run_cell currently captures all exceptions
2582 # self.run_cell currently captures all exceptions
2583 # raised in user code. It would be nice if there were
2583 # raised in user code. It would be nice if there were
2584 # versions of run_cell that did raise, so
2584 # versions of run_cell that did raise, so
2585 # we could catch the errors.
2585 # we could catch the errors.
2586 self.run_cell(cell, store_history=False, shell_futures=False)
2586 self.run_cell(cell, store_history=False, shell_futures=False)
2587 except:
2587 except:
2588 self.showtraceback()
2588 self.showtraceback()
2589 warn('Unknown failure executing file: <%s>' % fname)
2589 warn('Unknown failure executing file: <%s>' % fname)
2590
2590
2591 def safe_run_module(self, mod_name, where):
2591 def safe_run_module(self, mod_name, where):
2592 """A safe version of runpy.run_module().
2592 """A safe version of runpy.run_module().
2593
2593
2594 This version will never throw an exception, but instead print
2594 This version will never throw an exception, but instead print
2595 helpful error messages to the screen.
2595 helpful error messages to the screen.
2596
2596
2597 `SystemExit` exceptions with status code 0 or None are ignored.
2597 `SystemExit` exceptions with status code 0 or None are ignored.
2598
2598
2599 Parameters
2599 Parameters
2600 ----------
2600 ----------
2601 mod_name : string
2601 mod_name : string
2602 The name of the module to be executed.
2602 The name of the module to be executed.
2603 where : dict
2603 where : dict
2604 The globals namespace.
2604 The globals namespace.
2605 """
2605 """
2606 try:
2606 try:
2607 try:
2607 try:
2608 where.update(
2608 where.update(
2609 runpy.run_module(str(mod_name), run_name="__main__",
2609 runpy.run_module(str(mod_name), run_name="__main__",
2610 alter_sys=True)
2610 alter_sys=True)
2611 )
2611 )
2612 except SystemExit as status:
2612 except SystemExit as status:
2613 if status.code:
2613 if status.code:
2614 raise
2614 raise
2615 except:
2615 except:
2616 self.showtraceback()
2616 self.showtraceback()
2617 warn('Unknown failure executing module: <%s>' % mod_name)
2617 warn('Unknown failure executing module: <%s>' % mod_name)
2618
2618
2619 def _run_cached_cell_magic(self, magic_name, line):
2619 def _run_cached_cell_magic(self, magic_name, line):
2620 """Special method to call a cell magic with the data stored in self.
2620 """Special method to call a cell magic with the data stored in self.
2621 """
2621 """
2622 cell = self._current_cell_magic_body
2622 cell = self._current_cell_magic_body
2623 self._current_cell_magic_body = None
2623 self._current_cell_magic_body = None
2624 return self.run_cell_magic(magic_name, line, cell)
2624 return self.run_cell_magic(magic_name, line, cell)
2625
2625
2626 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2626 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2627 """Run a complete IPython cell.
2627 """Run a complete IPython cell.
2628
2628
2629 Parameters
2629 Parameters
2630 ----------
2630 ----------
2631 raw_cell : str
2631 raw_cell : str
2632 The code (including IPython code such as %magic functions) to run.
2632 The code (including IPython code such as %magic functions) to run.
2633 store_history : bool
2633 store_history : bool
2634 If True, the raw and translated cell will be stored in IPython's
2634 If True, the raw and translated cell will be stored in IPython's
2635 history. For user code calling back into IPython's machinery, this
2635 history. For user code calling back into IPython's machinery, this
2636 should be set to False.
2636 should be set to False.
2637 silent : bool
2637 silent : bool
2638 If True, avoid side-effects, such as implicit displayhooks and
2638 If True, avoid side-effects, such as implicit displayhooks and
2639 and logging. silent=True forces store_history=False.
2639 and logging. silent=True forces store_history=False.
2640 shell_futures : bool
2640 shell_futures : bool
2641 If True, the code will share future statements with the interactive
2641 If True, the code will share future statements with the interactive
2642 shell. It will both be affected by previous __future__ imports, and
2642 shell. It will both be affected by previous __future__ imports, and
2643 any __future__ imports in the code will affect the shell. If False,
2643 any __future__ imports in the code will affect the shell. If False,
2644 __future__ imports are not shared in either direction.
2644 __future__ imports are not shared in either direction.
2645 """
2645 """
2646 if (not raw_cell) or raw_cell.isspace():
2646 if (not raw_cell) or raw_cell.isspace():
2647 return
2647 return
2648
2648
2649 if silent:
2649 if silent:
2650 store_history = False
2650 store_history = False
2651
2651
2652 self.input_transformer_manager.push(raw_cell)
2652 # If any of our input transformation (input_transformer_manager or
2653 cell = self.input_transformer_manager.source_reset()
2653 # prefilter_manager) raises an exception, we store it in this variable
2654 # so that we can display the error after logging the input and storing
2655 # it in the history.
2656 preprocessing_exc_tuple = None
2657 try:
2658 # Static input transformations
2659 cell = self.input_transformer_manager.transform_cell(raw_cell)
2660 except SyntaxError:
2661 preprocessing_exc_tuple = sys.exc_info()
2662 cell = raw_cell # cell has to exist so it can be stored/logged
2663 else:
2664 if len(cell.splitlines()) == 1:
2665 # Dynamic transformations - only applied for single line commands
2666 with self.builtin_trap:
2667 try:
2668 # use prefilter_lines to handle trailing newlines
2669 # restore trailing newline for ast.parse
2670 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2671 except Exception:
2672 # don't allow prefilter errors to crash IPython
2673 preprocessing_exc_tuple = sys.exc_info()
2674
2675 # Store raw and processed history
2676 if store_history:
2677 self.history_manager.store_inputs(self.execution_count,
2678 cell, raw_cell)
2679 if not silent:
2680 self.logger.log(cell, raw_cell)
2681
2682 # Display the exception if input processing failed.
2683 if preprocessing_exc_tuple is not None:
2684 self.showtraceback(preprocessing_exc_tuple)
2685 if store_history:
2686 self.execution_count += 1
2687 return
2654
2688
2655 # Our own compiler remembers the __future__ environment. If we want to
2689 # Our own compiler remembers the __future__ environment. If we want to
2656 # run code with a separate __future__ environment, use the default
2690 # run code with a separate __future__ environment, use the default
2657 # compiler
2691 # compiler
2658 compiler = self.compile if shell_futures else CachingCompiler()
2692 compiler = self.compile if shell_futures else CachingCompiler()
2659
2693
2660 with self.builtin_trap:
2694 with self.builtin_trap:
2661 prefilter_failed = False
2695 cell_name = self.compile.cache(cell, self.execution_count)
2662 if len(cell.splitlines()) == 1:
2663 try:
2664 # use prefilter_lines to handle trailing newlines
2665 # restore trailing newline for ast.parse
2666 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2667 except AliasError as e:
2668 error(e)
2669 prefilter_failed = True
2670 except Exception:
2671 # don't allow prefilter errors to crash IPython
2672 self.showtraceback()
2673 prefilter_failed = True
2674
2675 # Store raw and processed history
2676 if store_history:
2677 self.history_manager.store_inputs(self.execution_count,
2678 cell, raw_cell)
2679 if not silent:
2680 self.logger.log(cell, raw_cell)
2681
2696
2682 if not prefilter_failed:
2697 with self.display_trap:
2683 # don't run if prefilter failed
2698 # Compile to bytecode
2684 cell_name = self.compile.cache(cell, self.execution_count)
2699 try:
2685
2700 code_ast = compiler.ast_parse(cell, filename=cell_name)
2686 with self.display_trap:
2701 except IndentationError:
2702 self.showindentationerror()
2703 if store_history:
2704 self.execution_count += 1
2705 return None
2706 except (OverflowError, SyntaxError, ValueError, TypeError,
2707 MemoryError):
2708 self.showsyntaxerror()
2709 if store_history:
2710 self.execution_count += 1
2711 return None
2712
2713 # Apply AST transformations
2714 code_ast = self.transform_ast(code_ast)
2715
2716 # Execute the user code
2717 interactivity = "none" if silent else self.ast_node_interactivity
2718 self.run_ast_nodes(code_ast.body, cell_name,
2719 interactivity=interactivity, compiler=compiler)
2720
2721 # Execute any registered post-execution functions.
2722 # unless we are silent
2723 post_exec = [] if silent else iteritems(self._post_execute)
2724
2725 for func, status in post_exec:
2726 if self.disable_failing_post_execute and not status:
2727 continue
2687 try:
2728 try:
2688 code_ast = compiler.ast_parse(cell, filename=cell_name)
2729 func()
2689 except IndentationError:
2730 except KeyboardInterrupt:
2690 self.showindentationerror()
2731 print("\nKeyboardInterrupt", file=io.stderr)
2691 if store_history:
2732 except Exception:
2692 self.execution_count += 1
2733 # register as failing:
2693 return None
2734 self._post_execute[func] = False
2694 except (OverflowError, SyntaxError, ValueError, TypeError,
2735 self.showtraceback()
2695 MemoryError):
2736 print('\n'.join([
2696 self.showsyntaxerror()
2737 "post-execution function %r produced an error." % func,
2697 if store_history:
2738 "If this problem persists, you can disable failing post-exec functions with:",
2698 self.execution_count += 1
2739 "",
2699 return None
2740 " get_ipython().disable_failing_post_execute = True"
2700
2741 ]), file=io.stderr)
2701 code_ast = self.transform_ast(code_ast)
2702
2703 interactivity = "none" if silent else self.ast_node_interactivity
2704 self.run_ast_nodes(code_ast.body, cell_name,
2705 interactivity=interactivity, compiler=compiler)
2706
2707 # Execute any registered post-execution functions.
2708 # unless we are silent
2709 post_exec = [] if silent else iteritems(self._post_execute)
2710
2711 for func, status in post_exec:
2712 if self.disable_failing_post_execute and not status:
2713 continue
2714 try:
2715 func()
2716 except KeyboardInterrupt:
2717 print("\nKeyboardInterrupt", file=io.stderr)
2718 except Exception:
2719 # register as failing:
2720 self._post_execute[func] = False
2721 self.showtraceback()
2722 print('\n'.join([
2723 "post-execution function %r produced an error." % func,
2724 "If this problem persists, you can disable failing post-exec functions with:",
2725 "",
2726 " get_ipython().disable_failing_post_execute = True"
2727 ]), file=io.stderr)
2728
2742
2729 if store_history:
2743 if store_history:
2730 # Write output to the database. Does nothing unless
2744 # Write output to the database. Does nothing unless
2731 # history output logging is enabled.
2745 # history output logging is enabled.
2732 self.history_manager.store_output(self.execution_count)
2746 self.history_manager.store_output(self.execution_count)
2733 # Each cell is a *single* input, regardless of how many lines it has
2747 # Each cell is a *single* input, regardless of how many lines it has
2734 self.execution_count += 1
2748 self.execution_count += 1
2735
2749
2736 def transform_ast(self, node):
2750 def transform_ast(self, node):
2737 """Apply the AST transformations from self.ast_transformers
2751 """Apply the AST transformations from self.ast_transformers
2738
2752
2739 Parameters
2753 Parameters
2740 ----------
2754 ----------
2741 node : ast.Node
2755 node : ast.Node
2742 The root node to be transformed. Typically called with the ast.Module
2756 The root node to be transformed. Typically called with the ast.Module
2743 produced by parsing user input.
2757 produced by parsing user input.
2744
2758
2745 Returns
2759 Returns
2746 -------
2760 -------
2747 An ast.Node corresponding to the node it was called with. Note that it
2761 An ast.Node corresponding to the node it was called with. Note that it
2748 may also modify the passed object, so don't rely on references to the
2762 may also modify the passed object, so don't rely on references to the
2749 original AST.
2763 original AST.
2750 """
2764 """
2751 for transformer in self.ast_transformers:
2765 for transformer in self.ast_transformers:
2752 try:
2766 try:
2753 node = transformer.visit(node)
2767 node = transformer.visit(node)
2754 except Exception:
2768 except Exception:
2755 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2769 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2756 self.ast_transformers.remove(transformer)
2770 self.ast_transformers.remove(transformer)
2757
2771
2758 if self.ast_transformers:
2772 if self.ast_transformers:
2759 ast.fix_missing_locations(node)
2773 ast.fix_missing_locations(node)
2760 return node
2774 return node
2761
2775
2762
2776
2763 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2777 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2764 compiler=compile):
2778 compiler=compile):
2765 """Run a sequence of AST nodes. The execution mode depends on the
2779 """Run a sequence of AST nodes. The execution mode depends on the
2766 interactivity parameter.
2780 interactivity parameter.
2767
2781
2768 Parameters
2782 Parameters
2769 ----------
2783 ----------
2770 nodelist : list
2784 nodelist : list
2771 A sequence of AST nodes to run.
2785 A sequence of AST nodes to run.
2772 cell_name : str
2786 cell_name : str
2773 Will be passed to the compiler as the filename of the cell. Typically
2787 Will be passed to the compiler as the filename of the cell. Typically
2774 the value returned by ip.compile.cache(cell).
2788 the value returned by ip.compile.cache(cell).
2775 interactivity : str
2789 interactivity : str
2776 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2790 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2777 run interactively (displaying output from expressions). 'last_expr'
2791 run interactively (displaying output from expressions). 'last_expr'
2778 will run the last node interactively only if it is an expression (i.e.
2792 will run the last node interactively only if it is an expression (i.e.
2779 expressions in loops or other blocks are not displayed. Other values
2793 expressions in loops or other blocks are not displayed. Other values
2780 for this parameter will raise a ValueError.
2794 for this parameter will raise a ValueError.
2781 compiler : callable
2795 compiler : callable
2782 A function with the same interface as the built-in compile(), to turn
2796 A function with the same interface as the built-in compile(), to turn
2783 the AST nodes into code objects. Default is the built-in compile().
2797 the AST nodes into code objects. Default is the built-in compile().
2784 """
2798 """
2785 if not nodelist:
2799 if not nodelist:
2786 return
2800 return
2787
2801
2788 if interactivity == 'last_expr':
2802 if interactivity == 'last_expr':
2789 if isinstance(nodelist[-1], ast.Expr):
2803 if isinstance(nodelist[-1], ast.Expr):
2790 interactivity = "last"
2804 interactivity = "last"
2791 else:
2805 else:
2792 interactivity = "none"
2806 interactivity = "none"
2793
2807
2794 if interactivity == 'none':
2808 if interactivity == 'none':
2795 to_run_exec, to_run_interactive = nodelist, []
2809 to_run_exec, to_run_interactive = nodelist, []
2796 elif interactivity == 'last':
2810 elif interactivity == 'last':
2797 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2811 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2798 elif interactivity == 'all':
2812 elif interactivity == 'all':
2799 to_run_exec, to_run_interactive = [], nodelist
2813 to_run_exec, to_run_interactive = [], nodelist
2800 else:
2814 else:
2801 raise ValueError("Interactivity was %r" % interactivity)
2815 raise ValueError("Interactivity was %r" % interactivity)
2802
2816
2803 exec_count = self.execution_count
2817 exec_count = self.execution_count
2804
2818
2805 try:
2819 try:
2806 for i, node in enumerate(to_run_exec):
2820 for i, node in enumerate(to_run_exec):
2807 mod = ast.Module([node])
2821 mod = ast.Module([node])
2808 code = compiler(mod, cell_name, "exec")
2822 code = compiler(mod, cell_name, "exec")
2809 if self.run_code(code):
2823 if self.run_code(code):
2810 return True
2824 return True
2811
2825
2812 for i, node in enumerate(to_run_interactive):
2826 for i, node in enumerate(to_run_interactive):
2813 mod = ast.Interactive([node])
2827 mod = ast.Interactive([node])
2814 code = compiler(mod, cell_name, "single")
2828 code = compiler(mod, cell_name, "single")
2815 if self.run_code(code):
2829 if self.run_code(code):
2816 return True
2830 return True
2817
2831
2818 # Flush softspace
2832 # Flush softspace
2819 if softspace(sys.stdout, 0):
2833 if softspace(sys.stdout, 0):
2820 print()
2834 print()
2821
2835
2822 except:
2836 except:
2823 # It's possible to have exceptions raised here, typically by
2837 # It's possible to have exceptions raised here, typically by
2824 # compilation of odd code (such as a naked 'return' outside a
2838 # compilation of odd code (such as a naked 'return' outside a
2825 # function) that did parse but isn't valid. Typically the exception
2839 # function) that did parse but isn't valid. Typically the exception
2826 # is a SyntaxError, but it's safest just to catch anything and show
2840 # is a SyntaxError, but it's safest just to catch anything and show
2827 # the user a traceback.
2841 # the user a traceback.
2828
2842
2829 # We do only one try/except outside the loop to minimize the impact
2843 # We do only one try/except outside the loop to minimize the impact
2830 # on runtime, and also because if any node in the node list is
2844 # on runtime, and also because if any node in the node list is
2831 # broken, we should stop execution completely.
2845 # broken, we should stop execution completely.
2832 self.showtraceback()
2846 self.showtraceback()
2833
2847
2834 return False
2848 return False
2835
2849
2836 def run_code(self, code_obj):
2850 def run_code(self, code_obj):
2837 """Execute a code object.
2851 """Execute a code object.
2838
2852
2839 When an exception occurs, self.showtraceback() is called to display a
2853 When an exception occurs, self.showtraceback() is called to display a
2840 traceback.
2854 traceback.
2841
2855
2842 Parameters
2856 Parameters
2843 ----------
2857 ----------
2844 code_obj : code object
2858 code_obj : code object
2845 A compiled code object, to be executed
2859 A compiled code object, to be executed
2846
2860
2847 Returns
2861 Returns
2848 -------
2862 -------
2849 False : successful execution.
2863 False : successful execution.
2850 True : an error occurred.
2864 True : an error occurred.
2851 """
2865 """
2852
2866
2853 # Set our own excepthook in case the user code tries to call it
2867 # Set our own excepthook in case the user code tries to call it
2854 # directly, so that the IPython crash handler doesn't get triggered
2868 # directly, so that the IPython crash handler doesn't get triggered
2855 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2869 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2856
2870
2857 # we save the original sys.excepthook in the instance, in case config
2871 # we save the original sys.excepthook in the instance, in case config
2858 # code (such as magics) needs access to it.
2872 # code (such as magics) needs access to it.
2859 self.sys_excepthook = old_excepthook
2873 self.sys_excepthook = old_excepthook
2860 outflag = 1 # happens in more places, so it's easier as default
2874 outflag = 1 # happens in more places, so it's easier as default
2861 try:
2875 try:
2862 try:
2876 try:
2863 self.hooks.pre_run_code_hook()
2877 self.hooks.pre_run_code_hook()
2864 #rprint('Running code', repr(code_obj)) # dbg
2878 #rprint('Running code', repr(code_obj)) # dbg
2865 exec(code_obj, self.user_global_ns, self.user_ns)
2879 exec(code_obj, self.user_global_ns, self.user_ns)
2866 finally:
2880 finally:
2867 # Reset our crash handler in place
2881 # Reset our crash handler in place
2868 sys.excepthook = old_excepthook
2882 sys.excepthook = old_excepthook
2869 except SystemExit:
2883 except SystemExit:
2870 self.showtraceback(exception_only=True)
2884 self.showtraceback(exception_only=True)
2871 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2885 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2872 except self.custom_exceptions:
2886 except self.custom_exceptions:
2873 etype,value,tb = sys.exc_info()
2887 etype,value,tb = sys.exc_info()
2874 self.CustomTB(etype,value,tb)
2888 self.CustomTB(etype,value,tb)
2875 except:
2889 except:
2876 self.showtraceback()
2890 self.showtraceback()
2877 else:
2891 else:
2878 outflag = 0
2892 outflag = 0
2879 return outflag
2893 return outflag
2880
2894
2881 # For backwards compatibility
2895 # For backwards compatibility
2882 runcode = run_code
2896 runcode = run_code
2883
2897
2884 #-------------------------------------------------------------------------
2898 #-------------------------------------------------------------------------
2885 # Things related to GUI support and pylab
2899 # Things related to GUI support and pylab
2886 #-------------------------------------------------------------------------
2900 #-------------------------------------------------------------------------
2887
2901
2888 def enable_gui(self, gui=None):
2902 def enable_gui(self, gui=None):
2889 raise NotImplementedError('Implement enable_gui in a subclass')
2903 raise NotImplementedError('Implement enable_gui in a subclass')
2890
2904
2891 def enable_matplotlib(self, gui=None):
2905 def enable_matplotlib(self, gui=None):
2892 """Enable interactive matplotlib and inline figure support.
2906 """Enable interactive matplotlib and inline figure support.
2893
2907
2894 This takes the following steps:
2908 This takes the following steps:
2895
2909
2896 1. select the appropriate eventloop and matplotlib backend
2910 1. select the appropriate eventloop and matplotlib backend
2897 2. set up matplotlib for interactive use with that backend
2911 2. set up matplotlib for interactive use with that backend
2898 3. configure formatters for inline figure display
2912 3. configure formatters for inline figure display
2899 4. enable the selected gui eventloop
2913 4. enable the selected gui eventloop
2900
2914
2901 Parameters
2915 Parameters
2902 ----------
2916 ----------
2903 gui : optional, string
2917 gui : optional, string
2904 If given, dictates the choice of matplotlib GUI backend to use
2918 If given, dictates the choice of matplotlib GUI backend to use
2905 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2919 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2906 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2920 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2907 matplotlib (as dictated by the matplotlib build-time options plus the
2921 matplotlib (as dictated by the matplotlib build-time options plus the
2908 user's matplotlibrc configuration file). Note that not all backends
2922 user's matplotlibrc configuration file). Note that not all backends
2909 make sense in all contexts, for example a terminal ipython can't
2923 make sense in all contexts, for example a terminal ipython can't
2910 display figures inline.
2924 display figures inline.
2911 """
2925 """
2912 from IPython.core import pylabtools as pt
2926 from IPython.core import pylabtools as pt
2913 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2927 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2914
2928
2915 if gui != 'inline':
2929 if gui != 'inline':
2916 # If we have our first gui selection, store it
2930 # If we have our first gui selection, store it
2917 if self.pylab_gui_select is None:
2931 if self.pylab_gui_select is None:
2918 self.pylab_gui_select = gui
2932 self.pylab_gui_select = gui
2919 # Otherwise if they are different
2933 # Otherwise if they are different
2920 elif gui != self.pylab_gui_select:
2934 elif gui != self.pylab_gui_select:
2921 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2935 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2922 ' Using %s instead.' % (gui, self.pylab_gui_select))
2936 ' Using %s instead.' % (gui, self.pylab_gui_select))
2923 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2937 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2924
2938
2925 pt.activate_matplotlib(backend)
2939 pt.activate_matplotlib(backend)
2926 pt.configure_inline_support(self, backend)
2940 pt.configure_inline_support(self, backend)
2927
2941
2928 # Now we must activate the gui pylab wants to use, and fix %run to take
2942 # Now we must activate the gui pylab wants to use, and fix %run to take
2929 # plot updates into account
2943 # plot updates into account
2930 self.enable_gui(gui)
2944 self.enable_gui(gui)
2931 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2945 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2932 pt.mpl_runner(self.safe_execfile)
2946 pt.mpl_runner(self.safe_execfile)
2933
2947
2934 return gui, backend
2948 return gui, backend
2935
2949
2936 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2950 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2937 """Activate pylab support at runtime.
2951 """Activate pylab support at runtime.
2938
2952
2939 This turns on support for matplotlib, preloads into the interactive
2953 This turns on support for matplotlib, preloads into the interactive
2940 namespace all of numpy and pylab, and configures IPython to correctly
2954 namespace all of numpy and pylab, and configures IPython to correctly
2941 interact with the GUI event loop. The GUI backend to be used can be
2955 interact with the GUI event loop. The GUI backend to be used can be
2942 optionally selected with the optional ``gui`` argument.
2956 optionally selected with the optional ``gui`` argument.
2943
2957
2944 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2958 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2945
2959
2946 Parameters
2960 Parameters
2947 ----------
2961 ----------
2948 gui : optional, string
2962 gui : optional, string
2949 If given, dictates the choice of matplotlib GUI backend to use
2963 If given, dictates the choice of matplotlib GUI backend to use
2950 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2964 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2951 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2965 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2952 matplotlib (as dictated by the matplotlib build-time options plus the
2966 matplotlib (as dictated by the matplotlib build-time options plus the
2953 user's matplotlibrc configuration file). Note that not all backends
2967 user's matplotlibrc configuration file). Note that not all backends
2954 make sense in all contexts, for example a terminal ipython can't
2968 make sense in all contexts, for example a terminal ipython can't
2955 display figures inline.
2969 display figures inline.
2956 import_all : optional, bool, default: True
2970 import_all : optional, bool, default: True
2957 Whether to do `from numpy import *` and `from pylab import *`
2971 Whether to do `from numpy import *` and `from pylab import *`
2958 in addition to module imports.
2972 in addition to module imports.
2959 welcome_message : deprecated
2973 welcome_message : deprecated
2960 This argument is ignored, no welcome message will be displayed.
2974 This argument is ignored, no welcome message will be displayed.
2961 """
2975 """
2962 from IPython.core.pylabtools import import_pylab
2976 from IPython.core.pylabtools import import_pylab
2963
2977
2964 gui, backend = self.enable_matplotlib(gui)
2978 gui, backend = self.enable_matplotlib(gui)
2965
2979
2966 # We want to prevent the loading of pylab to pollute the user's
2980 # We want to prevent the loading of pylab to pollute the user's
2967 # namespace as shown by the %who* magics, so we execute the activation
2981 # namespace as shown by the %who* magics, so we execute the activation
2968 # code in an empty namespace, and we update *both* user_ns and
2982 # code in an empty namespace, and we update *both* user_ns and
2969 # user_ns_hidden with this information.
2983 # user_ns_hidden with this information.
2970 ns = {}
2984 ns = {}
2971 import_pylab(ns, import_all)
2985 import_pylab(ns, import_all)
2972 # warn about clobbered names
2986 # warn about clobbered names
2973 ignored = set(["__builtins__"])
2987 ignored = set(["__builtins__"])
2974 both = set(ns).intersection(self.user_ns).difference(ignored)
2988 both = set(ns).intersection(self.user_ns).difference(ignored)
2975 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2989 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2976 self.user_ns.update(ns)
2990 self.user_ns.update(ns)
2977 self.user_ns_hidden.update(ns)
2991 self.user_ns_hidden.update(ns)
2978 return gui, backend, clobbered
2992 return gui, backend, clobbered
2979
2993
2980 #-------------------------------------------------------------------------
2994 #-------------------------------------------------------------------------
2981 # Utilities
2995 # Utilities
2982 #-------------------------------------------------------------------------
2996 #-------------------------------------------------------------------------
2983
2997
2984 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2998 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2985 """Expand python variables in a string.
2999 """Expand python variables in a string.
2986
3000
2987 The depth argument indicates how many frames above the caller should
3001 The depth argument indicates how many frames above the caller should
2988 be walked to look for the local namespace where to expand variables.
3002 be walked to look for the local namespace where to expand variables.
2989
3003
2990 The global namespace for expansion is always the user's interactive
3004 The global namespace for expansion is always the user's interactive
2991 namespace.
3005 namespace.
2992 """
3006 """
2993 ns = self.user_ns.copy()
3007 ns = self.user_ns.copy()
2994 ns.update(sys._getframe(depth+1).f_locals)
3008 ns.update(sys._getframe(depth+1).f_locals)
2995 try:
3009 try:
2996 # We have to use .vformat() here, because 'self' is a valid and common
3010 # We have to use .vformat() here, because 'self' is a valid and common
2997 # name, and expanding **ns for .format() would make it collide with
3011 # name, and expanding **ns for .format() would make it collide with
2998 # the 'self' argument of the method.
3012 # the 'self' argument of the method.
2999 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3013 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3000 except Exception:
3014 except Exception:
3001 # if formatter couldn't format, just let it go untransformed
3015 # if formatter couldn't format, just let it go untransformed
3002 pass
3016 pass
3003 return cmd
3017 return cmd
3004
3018
3005 def mktempfile(self, data=None, prefix='ipython_edit_'):
3019 def mktempfile(self, data=None, prefix='ipython_edit_'):
3006 """Make a new tempfile and return its filename.
3020 """Make a new tempfile and return its filename.
3007
3021
3008 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3022 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3009 but it registers the created filename internally so ipython cleans it up
3023 but it registers the created filename internally so ipython cleans it up
3010 at exit time.
3024 at exit time.
3011
3025
3012 Optional inputs:
3026 Optional inputs:
3013
3027
3014 - data(None): if data is given, it gets written out to the temp file
3028 - data(None): if data is given, it gets written out to the temp file
3015 immediately, and the file is closed again."""
3029 immediately, and the file is closed again."""
3016
3030
3017 dirname = tempfile.mkdtemp(prefix=prefix)
3031 dirname = tempfile.mkdtemp(prefix=prefix)
3018 self.tempdirs.append(dirname)
3032 self.tempdirs.append(dirname)
3019
3033
3020 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3034 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3021 self.tempfiles.append(filename)
3035 self.tempfiles.append(filename)
3022
3036
3023 if data:
3037 if data:
3024 tmp_file = open(filename,'w')
3038 tmp_file = open(filename,'w')
3025 tmp_file.write(data)
3039 tmp_file.write(data)
3026 tmp_file.close()
3040 tmp_file.close()
3027 return filename
3041 return filename
3028
3042
3029 # TODO: This should be removed when Term is refactored.
3043 # TODO: This should be removed when Term is refactored.
3030 def write(self,data):
3044 def write(self,data):
3031 """Write a string to the default output"""
3045 """Write a string to the default output"""
3032 io.stdout.write(data)
3046 io.stdout.write(data)
3033
3047
3034 # TODO: This should be removed when Term is refactored.
3048 # TODO: This should be removed when Term is refactored.
3035 def write_err(self,data):
3049 def write_err(self,data):
3036 """Write a string to the default error output"""
3050 """Write a string to the default error output"""
3037 io.stderr.write(data)
3051 io.stderr.write(data)
3038
3052
3039 def ask_yes_no(self, prompt, default=None):
3053 def ask_yes_no(self, prompt, default=None):
3040 if self.quiet:
3054 if self.quiet:
3041 return True
3055 return True
3042 return ask_yes_no(prompt,default)
3056 return ask_yes_no(prompt,default)
3043
3057
3044 def show_usage(self):
3058 def show_usage(self):
3045 """Show a usage message"""
3059 """Show a usage message"""
3046 page.page(IPython.core.usage.interactive_usage)
3060 page.page(IPython.core.usage.interactive_usage)
3047
3061
3048 def extract_input_lines(self, range_str, raw=False):
3062 def extract_input_lines(self, range_str, raw=False):
3049 """Return as a string a set of input history slices.
3063 """Return as a string a set of input history slices.
3050
3064
3051 Parameters
3065 Parameters
3052 ----------
3066 ----------
3053 range_str : string
3067 range_str : string
3054 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3068 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3055 since this function is for use by magic functions which get their
3069 since this function is for use by magic functions which get their
3056 arguments as strings. The number before the / is the session
3070 arguments as strings. The number before the / is the session
3057 number: ~n goes n back from the current session.
3071 number: ~n goes n back from the current session.
3058
3072
3059 raw : bool, optional
3073 raw : bool, optional
3060 By default, the processed input is used. If this is true, the raw
3074 By default, the processed input is used. If this is true, the raw
3061 input history is used instead.
3075 input history is used instead.
3062
3076
3063 Notes
3077 Notes
3064 -----
3078 -----
3065
3079
3066 Slices can be described with two notations:
3080 Slices can be described with two notations:
3067
3081
3068 * ``N:M`` -> standard python form, means including items N...(M-1).
3082 * ``N:M`` -> standard python form, means including items N...(M-1).
3069 * ``N-M`` -> include items N..M (closed endpoint).
3083 * ``N-M`` -> include items N..M (closed endpoint).
3070 """
3084 """
3071 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3085 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3072 return "\n".join(x for _, _, x in lines)
3086 return "\n".join(x for _, _, x in lines)
3073
3087
3074 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
3088 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
3075 """Get a code string from history, file, url, or a string or macro.
3089 """Get a code string from history, file, url, or a string or macro.
3076
3090
3077 This is mainly used by magic functions.
3091 This is mainly used by magic functions.
3078
3092
3079 Parameters
3093 Parameters
3080 ----------
3094 ----------
3081
3095
3082 target : str
3096 target : str
3083
3097
3084 A string specifying code to retrieve. This will be tried respectively
3098 A string specifying code to retrieve. This will be tried respectively
3085 as: ranges of input history (see %history for syntax), url,
3099 as: ranges of input history (see %history for syntax), url,
3086 correspnding .py file, filename, or an expression evaluating to a
3100 correspnding .py file, filename, or an expression evaluating to a
3087 string or Macro in the user namespace.
3101 string or Macro in the user namespace.
3088
3102
3089 raw : bool
3103 raw : bool
3090 If true (default), retrieve raw history. Has no effect on the other
3104 If true (default), retrieve raw history. Has no effect on the other
3091 retrieval mechanisms.
3105 retrieval mechanisms.
3092
3106
3093 py_only : bool (default False)
3107 py_only : bool (default False)
3094 Only try to fetch python code, do not try alternative methods to decode file
3108 Only try to fetch python code, do not try alternative methods to decode file
3095 if unicode fails.
3109 if unicode fails.
3096
3110
3097 Returns
3111 Returns
3098 -------
3112 -------
3099 A string of code.
3113 A string of code.
3100
3114
3101 ValueError is raised if nothing is found, and TypeError if it evaluates
3115 ValueError is raised if nothing is found, and TypeError if it evaluates
3102 to an object of another type. In each case, .args[0] is a printable
3116 to an object of another type. In each case, .args[0] is a printable
3103 message.
3117 message.
3104 """
3118 """
3105 code = self.extract_input_lines(target, raw=raw) # Grab history
3119 code = self.extract_input_lines(target, raw=raw) # Grab history
3106 if code:
3120 if code:
3107 return code
3121 return code
3108 utarget = unquote_filename(target)
3122 utarget = unquote_filename(target)
3109 try:
3123 try:
3110 if utarget.startswith(('http://', 'https://')):
3124 if utarget.startswith(('http://', 'https://')):
3111 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3125 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3112 except UnicodeDecodeError:
3126 except UnicodeDecodeError:
3113 if not py_only :
3127 if not py_only :
3114 # Deferred import
3128 # Deferred import
3115 try:
3129 try:
3116 from urllib.request import urlopen # Py3
3130 from urllib.request import urlopen # Py3
3117 except ImportError:
3131 except ImportError:
3118 from urllib import urlopen
3132 from urllib import urlopen
3119 response = urlopen(target)
3133 response = urlopen(target)
3120 return response.read().decode('latin1')
3134 return response.read().decode('latin1')
3121 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3135 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3122
3136
3123 potential_target = [target]
3137 potential_target = [target]
3124 try :
3138 try :
3125 potential_target.insert(0,get_py_filename(target))
3139 potential_target.insert(0,get_py_filename(target))
3126 except IOError:
3140 except IOError:
3127 pass
3141 pass
3128
3142
3129 for tgt in potential_target :
3143 for tgt in potential_target :
3130 if os.path.isfile(tgt): # Read file
3144 if os.path.isfile(tgt): # Read file
3131 try :
3145 try :
3132 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3146 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3133 except UnicodeDecodeError :
3147 except UnicodeDecodeError :
3134 if not py_only :
3148 if not py_only :
3135 with io_open(tgt,'r', encoding='latin1') as f :
3149 with io_open(tgt,'r', encoding='latin1') as f :
3136 return f.read()
3150 return f.read()
3137 raise ValueError(("'%s' seem to be unreadable.") % target)
3151 raise ValueError(("'%s' seem to be unreadable.") % target)
3138 elif os.path.isdir(os.path.expanduser(tgt)):
3152 elif os.path.isdir(os.path.expanduser(tgt)):
3139 raise ValueError("'%s' is a directory, not a regular file." % target)
3153 raise ValueError("'%s' is a directory, not a regular file." % target)
3140
3154
3141 try: # User namespace
3155 try: # User namespace
3142 codeobj = eval(target, self.user_ns)
3156 codeobj = eval(target, self.user_ns)
3143 except Exception:
3157 except Exception:
3144 raise ValueError(("'%s' was not found in history, as a file, url, "
3158 raise ValueError(("'%s' was not found in history, as a file, url, "
3145 "nor in the user namespace.") % target)
3159 "nor in the user namespace.") % target)
3146 if isinstance(codeobj, string_types):
3160 if isinstance(codeobj, string_types):
3147 return codeobj
3161 return codeobj
3148 elif isinstance(codeobj, Macro):
3162 elif isinstance(codeobj, Macro):
3149 return codeobj.value
3163 return codeobj.value
3150
3164
3151 raise TypeError("%s is neither a string nor a macro." % target,
3165 raise TypeError("%s is neither a string nor a macro." % target,
3152 codeobj)
3166 codeobj)
3153
3167
3154 #-------------------------------------------------------------------------
3168 #-------------------------------------------------------------------------
3155 # Things related to IPython exiting
3169 # Things related to IPython exiting
3156 #-------------------------------------------------------------------------
3170 #-------------------------------------------------------------------------
3157 def atexit_operations(self):
3171 def atexit_operations(self):
3158 """This will be executed at the time of exit.
3172 """This will be executed at the time of exit.
3159
3173
3160 Cleanup operations and saving of persistent data that is done
3174 Cleanup operations and saving of persistent data that is done
3161 unconditionally by IPython should be performed here.
3175 unconditionally by IPython should be performed here.
3162
3176
3163 For things that may depend on startup flags or platform specifics (such
3177 For things that may depend on startup flags or platform specifics (such
3164 as having readline or not), register a separate atexit function in the
3178 as having readline or not), register a separate atexit function in the
3165 code that has the appropriate information, rather than trying to
3179 code that has the appropriate information, rather than trying to
3166 clutter
3180 clutter
3167 """
3181 """
3168 # Close the history session (this stores the end time and line count)
3182 # Close the history session (this stores the end time and line count)
3169 # this must be *before* the tempfile cleanup, in case of temporary
3183 # this must be *before* the tempfile cleanup, in case of temporary
3170 # history db
3184 # history db
3171 self.history_manager.end_session()
3185 self.history_manager.end_session()
3172
3186
3173 # Cleanup all tempfiles and folders left around
3187 # Cleanup all tempfiles and folders left around
3174 for tfile in self.tempfiles:
3188 for tfile in self.tempfiles:
3175 try:
3189 try:
3176 os.unlink(tfile)
3190 os.unlink(tfile)
3177 except OSError:
3191 except OSError:
3178 pass
3192 pass
3179
3193
3180 for tdir in self.tempdirs:
3194 for tdir in self.tempdirs:
3181 try:
3195 try:
3182 os.rmdir(tdir)
3196 os.rmdir(tdir)
3183 except OSError:
3197 except OSError:
3184 pass
3198 pass
3185
3199
3186 # Clear all user namespaces to release all references cleanly.
3200 # Clear all user namespaces to release all references cleanly.
3187 self.reset(new_session=False)
3201 self.reset(new_session=False)
3188
3202
3189 # Run user hooks
3203 # Run user hooks
3190 self.hooks.shutdown_hook()
3204 self.hooks.shutdown_hook()
3191
3205
3192 def cleanup(self):
3206 def cleanup(self):
3193 self.restore_sys_module_state()
3207 self.restore_sys_module_state()
3194
3208
3195
3209
3196 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3210 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3197 """An abstract base class for InteractiveShell."""
3211 """An abstract base class for InteractiveShell."""
3198
3212
3199 InteractiveShellABC.register(InteractiveShell)
3213 InteractiveShellABC.register(InteractiveShell)
@@ -1,584 +1,585 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the inputsplitter module.
2 """Tests for the inputsplitter module.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Fernando Perez
6 * Fernando Perez
7 * Robert Kern
7 * Robert Kern
8 """
8 """
9 from __future__ import print_function
9 from __future__ import print_function
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2010-2011 The IPython Development Team
11 # Copyright (C) 2010-2011 The IPython Development Team
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # stdlib
20 # stdlib
21 import unittest
21 import unittest
22 import sys
22 import sys
23
23
24 # Third party
24 # Third party
25 import nose.tools as nt
25 import nose.tools as nt
26
26
27 # Our own
27 # Our own
28 from IPython.core import inputsplitter as isp
28 from IPython.core import inputsplitter as isp
29 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
29 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
30 from IPython.testing import tools as tt
30 from IPython.testing import tools as tt
31 from IPython.utils import py3compat
31 from IPython.utils import py3compat
32 from IPython.utils.py3compat import string_types, input
32 from IPython.utils.py3compat import string_types, input
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Semi-complete examples (also used as tests)
35 # Semi-complete examples (also used as tests)
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 # Note: at the bottom, there's a slightly more complete version of this that
38 # Note: at the bottom, there's a slightly more complete version of this that
39 # can be useful during development of code here.
39 # can be useful during development of code here.
40
40
41 def mini_interactive_loop(input_func):
41 def mini_interactive_loop(input_func):
42 """Minimal example of the logic of an interactive interpreter loop.
42 """Minimal example of the logic of an interactive interpreter loop.
43
43
44 This serves as an example, and it is used by the test system with a fake
44 This serves as an example, and it is used by the test system with a fake
45 raw_input that simulates interactive input."""
45 raw_input that simulates interactive input."""
46
46
47 from IPython.core.inputsplitter import InputSplitter
47 from IPython.core.inputsplitter import InputSplitter
48
48
49 isp = InputSplitter()
49 isp = InputSplitter()
50 # In practice, this input loop would be wrapped in an outside loop to read
50 # In practice, this input loop would be wrapped in an outside loop to read
51 # input indefinitely, until some exit/quit command was issued. Here we
51 # input indefinitely, until some exit/quit command was issued. Here we
52 # only illustrate the basic inner loop.
52 # only illustrate the basic inner loop.
53 while isp.push_accepts_more():
53 while isp.push_accepts_more():
54 indent = ' '*isp.indent_spaces
54 indent = ' '*isp.indent_spaces
55 prompt = '>>> ' + indent
55 prompt = '>>> ' + indent
56 line = indent + input_func(prompt)
56 line = indent + input_func(prompt)
57 isp.push(line)
57 isp.push(line)
58
58
59 # Here we just return input so we can use it in a test suite, but a real
59 # Here we just return input so we can use it in a test suite, but a real
60 # interpreter would instead send it for execution somewhere.
60 # interpreter would instead send it for execution somewhere.
61 src = isp.source_reset()
61 src = isp.source_reset()
62 #print 'Input source was:\n', src # dbg
62 #print 'Input source was:\n', src # dbg
63 return src
63 return src
64
64
65 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
66 # Test utilities, just for local use
66 # Test utilities, just for local use
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68
68
69 def assemble(block):
69 def assemble(block):
70 """Assemble a block into multi-line sub-blocks."""
70 """Assemble a block into multi-line sub-blocks."""
71 return ['\n'.join(sub_block)+'\n' for sub_block in block]
71 return ['\n'.join(sub_block)+'\n' for sub_block in block]
72
72
73
73
74 def pseudo_input(lines):
74 def pseudo_input(lines):
75 """Return a function that acts like raw_input but feeds the input list."""
75 """Return a function that acts like raw_input but feeds the input list."""
76 ilines = iter(lines)
76 ilines = iter(lines)
77 def raw_in(prompt):
77 def raw_in(prompt):
78 try:
78 try:
79 return next(ilines)
79 return next(ilines)
80 except StopIteration:
80 except StopIteration:
81 return ''
81 return ''
82 return raw_in
82 return raw_in
83
83
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85 # Tests
85 # Tests
86 #-----------------------------------------------------------------------------
86 #-----------------------------------------------------------------------------
87 def test_spaces():
87 def test_spaces():
88 tests = [('', 0),
88 tests = [('', 0),
89 (' ', 1),
89 (' ', 1),
90 ('\n', 0),
90 ('\n', 0),
91 (' \n', 1),
91 (' \n', 1),
92 ('x', 0),
92 ('x', 0),
93 (' x', 1),
93 (' x', 1),
94 (' x',2),
94 (' x',2),
95 (' x',4),
95 (' x',4),
96 # Note: tabs are counted as a single whitespace!
96 # Note: tabs are counted as a single whitespace!
97 ('\tx', 1),
97 ('\tx', 1),
98 ('\t x', 2),
98 ('\t x', 2),
99 ]
99 ]
100 tt.check_pairs(isp.num_ini_spaces, tests)
100 tt.check_pairs(isp.num_ini_spaces, tests)
101
101
102
102
103 def test_remove_comments():
103 def test_remove_comments():
104 tests = [('text', 'text'),
104 tests = [('text', 'text'),
105 ('text # comment', 'text '),
105 ('text # comment', 'text '),
106 ('text # comment\n', 'text \n'),
106 ('text # comment\n', 'text \n'),
107 ('text # comment \n', 'text \n'),
107 ('text # comment \n', 'text \n'),
108 ('line # c \nline\n','line \nline\n'),
108 ('line # c \nline\n','line \nline\n'),
109 ('line # c \nline#c2 \nline\nline #c\n\n',
109 ('line # c \nline#c2 \nline\nline #c\n\n',
110 'line \nline\nline\nline \n\n'),
110 'line \nline\nline\nline \n\n'),
111 ]
111 ]
112 tt.check_pairs(isp.remove_comments, tests)
112 tt.check_pairs(isp.remove_comments, tests)
113
113
114
114
115 def test_get_input_encoding():
115 def test_get_input_encoding():
116 encoding = isp.get_input_encoding()
116 encoding = isp.get_input_encoding()
117 nt.assert_true(isinstance(encoding, string_types))
117 nt.assert_true(isinstance(encoding, string_types))
118 # simple-minded check that at least encoding a simple string works with the
118 # simple-minded check that at least encoding a simple string works with the
119 # encoding we got.
119 # encoding we got.
120 nt.assert_equal(u'test'.encode(encoding), b'test')
120 nt.assert_equal(u'test'.encode(encoding), b'test')
121
121
122
122
123 class NoInputEncodingTestCase(unittest.TestCase):
123 class NoInputEncodingTestCase(unittest.TestCase):
124 def setUp(self):
124 def setUp(self):
125 self.old_stdin = sys.stdin
125 self.old_stdin = sys.stdin
126 class X: pass
126 class X: pass
127 fake_stdin = X()
127 fake_stdin = X()
128 sys.stdin = fake_stdin
128 sys.stdin = fake_stdin
129
129
130 def test(self):
130 def test(self):
131 # Verify that if sys.stdin has no 'encoding' attribute we do the right
131 # Verify that if sys.stdin has no 'encoding' attribute we do the right
132 # thing
132 # thing
133 enc = isp.get_input_encoding()
133 enc = isp.get_input_encoding()
134 self.assertEqual(enc, 'ascii')
134 self.assertEqual(enc, 'ascii')
135
135
136 def tearDown(self):
136 def tearDown(self):
137 sys.stdin = self.old_stdin
137 sys.stdin = self.old_stdin
138
138
139
139
140 class InputSplitterTestCase(unittest.TestCase):
140 class InputSplitterTestCase(unittest.TestCase):
141 def setUp(self):
141 def setUp(self):
142 self.isp = isp.InputSplitter()
142 self.isp = isp.InputSplitter()
143
143
144 def test_reset(self):
144 def test_reset(self):
145 isp = self.isp
145 isp = self.isp
146 isp.push('x=1')
146 isp.push('x=1')
147 isp.reset()
147 isp.reset()
148 self.assertEqual(isp._buffer, [])
148 self.assertEqual(isp._buffer, [])
149 self.assertEqual(isp.indent_spaces, 0)
149 self.assertEqual(isp.indent_spaces, 0)
150 self.assertEqual(isp.source, '')
150 self.assertEqual(isp.source, '')
151 self.assertEqual(isp.code, None)
151 self.assertEqual(isp.code, None)
152 self.assertEqual(isp._is_complete, False)
152 self.assertEqual(isp._is_complete, False)
153
153
154 def test_source(self):
154 def test_source(self):
155 self.isp._store('1')
155 self.isp._store('1')
156 self.isp._store('2')
156 self.isp._store('2')
157 self.assertEqual(self.isp.source, '1\n2\n')
157 self.assertEqual(self.isp.source, '1\n2\n')
158 self.assertTrue(len(self.isp._buffer)>0)
158 self.assertTrue(len(self.isp._buffer)>0)
159 self.assertEqual(self.isp.source_reset(), '1\n2\n')
159 self.assertEqual(self.isp.source_reset(), '1\n2\n')
160 self.assertEqual(self.isp._buffer, [])
160 self.assertEqual(self.isp._buffer, [])
161 self.assertEqual(self.isp.source, '')
161 self.assertEqual(self.isp.source, '')
162
162
163 def test_indent(self):
163 def test_indent(self):
164 isp = self.isp # shorthand
164 isp = self.isp # shorthand
165 isp.push('x=1')
165 isp.push('x=1')
166 self.assertEqual(isp.indent_spaces, 0)
166 self.assertEqual(isp.indent_spaces, 0)
167 isp.push('if 1:\n x=1')
167 isp.push('if 1:\n x=1')
168 self.assertEqual(isp.indent_spaces, 4)
168 self.assertEqual(isp.indent_spaces, 4)
169 isp.push('y=2\n')
169 isp.push('y=2\n')
170 self.assertEqual(isp.indent_spaces, 0)
170 self.assertEqual(isp.indent_spaces, 0)
171
171
172 def test_indent2(self):
172 def test_indent2(self):
173 isp = self.isp
173 isp = self.isp
174 isp.push('if 1:')
174 isp.push('if 1:')
175 self.assertEqual(isp.indent_spaces, 4)
175 self.assertEqual(isp.indent_spaces, 4)
176 isp.push(' x=1')
176 isp.push(' x=1')
177 self.assertEqual(isp.indent_spaces, 4)
177 self.assertEqual(isp.indent_spaces, 4)
178 # Blank lines shouldn't change the indent level
178 # Blank lines shouldn't change the indent level
179 isp.push(' '*2)
179 isp.push(' '*2)
180 self.assertEqual(isp.indent_spaces, 4)
180 self.assertEqual(isp.indent_spaces, 4)
181
181
182 def test_indent3(self):
182 def test_indent3(self):
183 isp = self.isp
183 isp = self.isp
184 # When a multiline statement contains parens or multiline strings, we
184 # When a multiline statement contains parens or multiline strings, we
185 # shouldn't get confused.
185 # shouldn't get confused.
186 isp.push("if 1:")
186 isp.push("if 1:")
187 isp.push(" x = (1+\n 2)")
187 isp.push(" x = (1+\n 2)")
188 self.assertEqual(isp.indent_spaces, 4)
188 self.assertEqual(isp.indent_spaces, 4)
189
189
190 def test_indent4(self):
190 def test_indent4(self):
191 isp = self.isp
191 isp = self.isp
192 # whitespace after ':' should not screw up indent level
192 # whitespace after ':' should not screw up indent level
193 isp.push('if 1: \n x=1')
193 isp.push('if 1: \n x=1')
194 self.assertEqual(isp.indent_spaces, 4)
194 self.assertEqual(isp.indent_spaces, 4)
195 isp.push('y=2\n')
195 isp.push('y=2\n')
196 self.assertEqual(isp.indent_spaces, 0)
196 self.assertEqual(isp.indent_spaces, 0)
197 isp.push('if 1:\t\n x=1')
197 isp.push('if 1:\t\n x=1')
198 self.assertEqual(isp.indent_spaces, 4)
198 self.assertEqual(isp.indent_spaces, 4)
199 isp.push('y=2\n')
199 isp.push('y=2\n')
200 self.assertEqual(isp.indent_spaces, 0)
200 self.assertEqual(isp.indent_spaces, 0)
201
201
202 def test_dedent_pass(self):
202 def test_dedent_pass(self):
203 isp = self.isp # shorthand
203 isp = self.isp # shorthand
204 # should NOT cause dedent
204 # should NOT cause dedent
205 isp.push('if 1:\n passes = 5')
205 isp.push('if 1:\n passes = 5')
206 self.assertEqual(isp.indent_spaces, 4)
206 self.assertEqual(isp.indent_spaces, 4)
207 isp.push('if 1:\n pass')
207 isp.push('if 1:\n pass')
208 self.assertEqual(isp.indent_spaces, 0)
208 self.assertEqual(isp.indent_spaces, 0)
209 isp.push('if 1:\n pass ')
209 isp.push('if 1:\n pass ')
210 self.assertEqual(isp.indent_spaces, 0)
210 self.assertEqual(isp.indent_spaces, 0)
211
211
212 def test_dedent_break(self):
212 def test_dedent_break(self):
213 isp = self.isp # shorthand
213 isp = self.isp # shorthand
214 # should NOT cause dedent
214 # should NOT cause dedent
215 isp.push('while 1:\n breaks = 5')
215 isp.push('while 1:\n breaks = 5')
216 self.assertEqual(isp.indent_spaces, 4)
216 self.assertEqual(isp.indent_spaces, 4)
217 isp.push('while 1:\n break')
217 isp.push('while 1:\n break')
218 self.assertEqual(isp.indent_spaces, 0)
218 self.assertEqual(isp.indent_spaces, 0)
219 isp.push('while 1:\n break ')
219 isp.push('while 1:\n break ')
220 self.assertEqual(isp.indent_spaces, 0)
220 self.assertEqual(isp.indent_spaces, 0)
221
221
222 def test_dedent_continue(self):
222 def test_dedent_continue(self):
223 isp = self.isp # shorthand
223 isp = self.isp # shorthand
224 # should NOT cause dedent
224 # should NOT cause dedent
225 isp.push('while 1:\n continues = 5')
225 isp.push('while 1:\n continues = 5')
226 self.assertEqual(isp.indent_spaces, 4)
226 self.assertEqual(isp.indent_spaces, 4)
227 isp.push('while 1:\n continue')
227 isp.push('while 1:\n continue')
228 self.assertEqual(isp.indent_spaces, 0)
228 self.assertEqual(isp.indent_spaces, 0)
229 isp.push('while 1:\n continue ')
229 isp.push('while 1:\n continue ')
230 self.assertEqual(isp.indent_spaces, 0)
230 self.assertEqual(isp.indent_spaces, 0)
231
231
232 def test_dedent_raise(self):
232 def test_dedent_raise(self):
233 isp = self.isp # shorthand
233 isp = self.isp # shorthand
234 # should NOT cause dedent
234 # should NOT cause dedent
235 isp.push('if 1:\n raised = 4')
235 isp.push('if 1:\n raised = 4')
236 self.assertEqual(isp.indent_spaces, 4)
236 self.assertEqual(isp.indent_spaces, 4)
237 isp.push('if 1:\n raise TypeError()')
237 isp.push('if 1:\n raise TypeError()')
238 self.assertEqual(isp.indent_spaces, 0)
238 self.assertEqual(isp.indent_spaces, 0)
239 isp.push('if 1:\n raise')
239 isp.push('if 1:\n raise')
240 self.assertEqual(isp.indent_spaces, 0)
240 self.assertEqual(isp.indent_spaces, 0)
241 isp.push('if 1:\n raise ')
241 isp.push('if 1:\n raise ')
242 self.assertEqual(isp.indent_spaces, 0)
242 self.assertEqual(isp.indent_spaces, 0)
243
243
244 def test_dedent_return(self):
244 def test_dedent_return(self):
245 isp = self.isp # shorthand
245 isp = self.isp # shorthand
246 # should NOT cause dedent
246 # should NOT cause dedent
247 isp.push('if 1:\n returning = 4')
247 isp.push('if 1:\n returning = 4')
248 self.assertEqual(isp.indent_spaces, 4)
248 self.assertEqual(isp.indent_spaces, 4)
249 isp.push('if 1:\n return 5 + 493')
249 isp.push('if 1:\n return 5 + 493')
250 self.assertEqual(isp.indent_spaces, 0)
250 self.assertEqual(isp.indent_spaces, 0)
251 isp.push('if 1:\n return')
251 isp.push('if 1:\n return')
252 self.assertEqual(isp.indent_spaces, 0)
252 self.assertEqual(isp.indent_spaces, 0)
253 isp.push('if 1:\n return ')
253 isp.push('if 1:\n return ')
254 self.assertEqual(isp.indent_spaces, 0)
254 self.assertEqual(isp.indent_spaces, 0)
255 isp.push('if 1:\n return(0)')
255 isp.push('if 1:\n return(0)')
256 self.assertEqual(isp.indent_spaces, 0)
256 self.assertEqual(isp.indent_spaces, 0)
257
257
258 def test_push(self):
258 def test_push(self):
259 isp = self.isp
259 isp = self.isp
260 self.assertTrue(isp.push('x=1'))
260 self.assertTrue(isp.push('x=1'))
261
261
262 def test_push2(self):
262 def test_push2(self):
263 isp = self.isp
263 isp = self.isp
264 self.assertFalse(isp.push('if 1:'))
264 self.assertFalse(isp.push('if 1:'))
265 for line in [' x=1', '# a comment', ' y=2']:
265 for line in [' x=1', '# a comment', ' y=2']:
266 print(line)
266 print(line)
267 self.assertTrue(isp.push(line))
267 self.assertTrue(isp.push(line))
268
268
269 def test_push3(self):
269 def test_push3(self):
270 isp = self.isp
270 isp = self.isp
271 isp.push('if True:')
271 isp.push('if True:')
272 isp.push(' a = 1')
272 isp.push(' a = 1')
273 self.assertFalse(isp.push('b = [1,'))
273 self.assertFalse(isp.push('b = [1,'))
274
274
275 def test_push_accepts_more(self):
275 def test_push_accepts_more(self):
276 isp = self.isp
276 isp = self.isp
277 isp.push('x=1')
277 isp.push('x=1')
278 self.assertFalse(isp.push_accepts_more())
278 self.assertFalse(isp.push_accepts_more())
279
279
280 def test_push_accepts_more2(self):
280 def test_push_accepts_more2(self):
281 isp = self.isp
281 isp = self.isp
282 isp.push('if 1:')
282 isp.push('if 1:')
283 self.assertTrue(isp.push_accepts_more())
283 self.assertTrue(isp.push_accepts_more())
284 isp.push(' x=1')
284 isp.push(' x=1')
285 self.assertTrue(isp.push_accepts_more())
285 self.assertTrue(isp.push_accepts_more())
286 isp.push('')
286 isp.push('')
287 self.assertFalse(isp.push_accepts_more())
287 self.assertFalse(isp.push_accepts_more())
288
288
289 def test_push_accepts_more3(self):
289 def test_push_accepts_more3(self):
290 isp = self.isp
290 isp = self.isp
291 isp.push("x = (2+\n3)")
291 isp.push("x = (2+\n3)")
292 self.assertFalse(isp.push_accepts_more())
292 self.assertFalse(isp.push_accepts_more())
293
293
294 def test_push_accepts_more4(self):
294 def test_push_accepts_more4(self):
295 isp = self.isp
295 isp = self.isp
296 # When a multiline statement contains parens or multiline strings, we
296 # When a multiline statement contains parens or multiline strings, we
297 # shouldn't get confused.
297 # shouldn't get confused.
298 # FIXME: we should be able to better handle de-dents in statements like
298 # FIXME: we should be able to better handle de-dents in statements like
299 # multiline strings and multiline expressions (continued with \ or
299 # multiline strings and multiline expressions (continued with \ or
300 # parens). Right now we aren't handling the indentation tracking quite
300 # parens). Right now we aren't handling the indentation tracking quite
301 # correctly with this, though in practice it may not be too much of a
301 # correctly with this, though in practice it may not be too much of a
302 # problem. We'll need to see.
302 # problem. We'll need to see.
303 isp.push("if 1:")
303 isp.push("if 1:")
304 isp.push(" x = (2+")
304 isp.push(" x = (2+")
305 isp.push(" 3)")
305 isp.push(" 3)")
306 self.assertTrue(isp.push_accepts_more())
306 self.assertTrue(isp.push_accepts_more())
307 isp.push(" y = 3")
307 isp.push(" y = 3")
308 self.assertTrue(isp.push_accepts_more())
308 self.assertTrue(isp.push_accepts_more())
309 isp.push('')
309 isp.push('')
310 self.assertFalse(isp.push_accepts_more())
310 self.assertFalse(isp.push_accepts_more())
311
311
312 def test_push_accepts_more5(self):
312 def test_push_accepts_more5(self):
313 isp = self.isp
313 isp = self.isp
314 isp.push('try:')
314 isp.push('try:')
315 isp.push(' a = 5')
315 isp.push(' a = 5')
316 isp.push('except:')
316 isp.push('except:')
317 isp.push(' raise')
317 isp.push(' raise')
318 # We want to be able to add an else: block at this point, so it should
318 # We want to be able to add an else: block at this point, so it should
319 # wait for a blank line.
319 # wait for a blank line.
320 self.assertTrue(isp.push_accepts_more())
320 self.assertTrue(isp.push_accepts_more())
321
321
322 def test_continuation(self):
322 def test_continuation(self):
323 isp = self.isp
323 isp = self.isp
324 isp.push("import os, \\")
324 isp.push("import os, \\")
325 self.assertTrue(isp.push_accepts_more())
325 self.assertTrue(isp.push_accepts_more())
326 isp.push("sys")
326 isp.push("sys")
327 self.assertFalse(isp.push_accepts_more())
327 self.assertFalse(isp.push_accepts_more())
328
328
329 def test_syntax_error(self):
329 def test_syntax_error(self):
330 isp = self.isp
330 isp = self.isp
331 # Syntax errors immediately produce a 'ready' block, so the invalid
331 # Syntax errors immediately produce a 'ready' block, so the invalid
332 # Python can be sent to the kernel for evaluation with possible ipython
332 # Python can be sent to the kernel for evaluation with possible ipython
333 # special-syntax conversion.
333 # special-syntax conversion.
334 isp.push('run foo')
334 isp.push('run foo')
335 self.assertFalse(isp.push_accepts_more())
335 self.assertFalse(isp.push_accepts_more())
336
336
337 def test_unicode(self):
337 def test_unicode(self):
338 self.isp.push(u"PΓ©rez")
338 self.isp.push(u"PΓ©rez")
339 self.isp.push(u'\xc3\xa9')
339 self.isp.push(u'\xc3\xa9')
340 self.isp.push(u"u'\xc3\xa9'")
340 self.isp.push(u"u'\xc3\xa9'")
341
341
342 def test_line_continuation(self):
342 def test_line_continuation(self):
343 """ Test issue #2108."""
343 """ Test issue #2108."""
344 isp = self.isp
344 isp = self.isp
345 # A blank line after a line continuation should not accept more
345 # A blank line after a line continuation should not accept more
346 isp.push("1 \\\n\n")
346 isp.push("1 \\\n\n")
347 self.assertFalse(isp.push_accepts_more())
347 self.assertFalse(isp.push_accepts_more())
348 # Whitespace after a \ is a SyntaxError. The only way to test that
348 # Whitespace after a \ is a SyntaxError. The only way to test that
349 # here is to test that push doesn't accept more (as with
349 # here is to test that push doesn't accept more (as with
350 # test_syntax_error() above).
350 # test_syntax_error() above).
351 isp.push(r"1 \ ")
351 isp.push(r"1 \ ")
352 self.assertFalse(isp.push_accepts_more())
352 self.assertFalse(isp.push_accepts_more())
353 # Even if the line is continuable (c.f. the regular Python
353 # Even if the line is continuable (c.f. the regular Python
354 # interpreter)
354 # interpreter)
355 isp.push(r"(1 \ ")
355 isp.push(r"(1 \ ")
356 self.assertFalse(isp.push_accepts_more())
356 self.assertFalse(isp.push_accepts_more())
357
357
358 class InteractiveLoopTestCase(unittest.TestCase):
358 class InteractiveLoopTestCase(unittest.TestCase):
359 """Tests for an interactive loop like a python shell.
359 """Tests for an interactive loop like a python shell.
360 """
360 """
361 def check_ns(self, lines, ns):
361 def check_ns(self, lines, ns):
362 """Validate that the given input lines produce the resulting namespace.
362 """Validate that the given input lines produce the resulting namespace.
363
363
364 Note: the input lines are given exactly as they would be typed in an
364 Note: the input lines are given exactly as they would be typed in an
365 auto-indenting environment, as mini_interactive_loop above already does
365 auto-indenting environment, as mini_interactive_loop above already does
366 auto-indenting and prepends spaces to the input.
366 auto-indenting and prepends spaces to the input.
367 """
367 """
368 src = mini_interactive_loop(pseudo_input(lines))
368 src = mini_interactive_loop(pseudo_input(lines))
369 test_ns = {}
369 test_ns = {}
370 exec(src, test_ns)
370 exec(src, test_ns)
371 # We can't check that the provided ns is identical to the test_ns,
371 # We can't check that the provided ns is identical to the test_ns,
372 # because Python fills test_ns with extra keys (copyright, etc). But
372 # because Python fills test_ns with extra keys (copyright, etc). But
373 # we can check that the given dict is *contained* in test_ns
373 # we can check that the given dict is *contained* in test_ns
374 for k,v in ns.items():
374 for k,v in ns.items():
375 self.assertEqual(test_ns[k], v)
375 self.assertEqual(test_ns[k], v)
376
376
377 def test_simple(self):
377 def test_simple(self):
378 self.check_ns(['x=1'], dict(x=1))
378 self.check_ns(['x=1'], dict(x=1))
379
379
380 def test_simple2(self):
380 def test_simple2(self):
381 self.check_ns(['if 1:', 'x=2'], dict(x=2))
381 self.check_ns(['if 1:', 'x=2'], dict(x=2))
382
382
383 def test_xy(self):
383 def test_xy(self):
384 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
384 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
385
385
386 def test_abc(self):
386 def test_abc(self):
387 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
387 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
388
388
389 def test_multi(self):
389 def test_multi(self):
390 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
390 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
391
391
392
392
393 class IPythonInputTestCase(InputSplitterTestCase):
393 class IPythonInputTestCase(InputSplitterTestCase):
394 """By just creating a new class whose .isp is a different instance, we
394 """By just creating a new class whose .isp is a different instance, we
395 re-run the same test battery on the new input splitter.
395 re-run the same test battery on the new input splitter.
396
396
397 In addition, this runs the tests over the syntax and syntax_ml dicts that
397 In addition, this runs the tests over the syntax and syntax_ml dicts that
398 were tested by individual functions, as part of the OO interface.
398 were tested by individual functions, as part of the OO interface.
399
399
400 It also makes some checks on the raw buffer storage.
400 It also makes some checks on the raw buffer storage.
401 """
401 """
402
402
403 def setUp(self):
403 def setUp(self):
404 self.isp = isp.IPythonInputSplitter()
404 self.isp = isp.IPythonInputSplitter()
405
405
406 def test_syntax(self):
406 def test_syntax(self):
407 """Call all single-line syntax tests from the main object"""
407 """Call all single-line syntax tests from the main object"""
408 isp = self.isp
408 isp = self.isp
409 for example in syntax.values():
409 for example in syntax.values():
410 for raw, out_t in example:
410 for raw, out_t in example:
411 if raw.startswith(' '):
411 if raw.startswith(' '):
412 continue
412 continue
413
413
414 isp.push(raw+'\n')
414 isp.push(raw+'\n')
415 out, out_raw = isp.source_raw_reset()
415 out_raw = isp.source_raw
416 out = isp.source_reset()
416 self.assertEqual(out.rstrip(), out_t,
417 self.assertEqual(out.rstrip(), out_t,
417 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
418 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
418 self.assertEqual(out_raw.rstrip(), raw.rstrip())
419 self.assertEqual(out_raw.rstrip(), raw.rstrip())
419
420
420 def test_syntax_multiline(self):
421 def test_syntax_multiline(self):
421 isp = self.isp
422 isp = self.isp
422 for example in syntax_ml.values():
423 for example in syntax_ml.values():
423 for line_pairs in example:
424 for line_pairs in example:
424 out_t_parts = []
425 out_t_parts = []
425 raw_parts = []
426 raw_parts = []
426 for lraw, out_t_part in line_pairs:
427 for lraw, out_t_part in line_pairs:
427 if out_t_part is not None:
428 if out_t_part is not None:
428 out_t_parts.append(out_t_part)
429 out_t_parts.append(out_t_part)
429
430
430 if lraw is not None:
431 if lraw is not None:
431 isp.push(lraw)
432 isp.push(lraw)
432 raw_parts.append(lraw)
433 raw_parts.append(lraw)
433
434
434 out, out_raw = isp.source_raw_reset()
435 out_raw = isp.source_raw
436 out = isp.source_reset()
435 out_t = '\n'.join(out_t_parts).rstrip()
437 out_t = '\n'.join(out_t_parts).rstrip()
436 raw = '\n'.join(raw_parts).rstrip()
438 raw = '\n'.join(raw_parts).rstrip()
437 self.assertEqual(out.rstrip(), out_t)
439 self.assertEqual(out.rstrip(), out_t)
438 self.assertEqual(out_raw.rstrip(), raw)
440 self.assertEqual(out_raw.rstrip(), raw)
439
441
440 def test_syntax_multiline_cell(self):
442 def test_syntax_multiline_cell(self):
441 isp = self.isp
443 isp = self.isp
442 for example in syntax_ml.values():
444 for example in syntax_ml.values():
443
445
444 out_t_parts = []
446 out_t_parts = []
445 for line_pairs in example:
447 for line_pairs in example:
446 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
448 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
447 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
449 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
448 out = isp.transform_cell(raw)
450 out = isp.transform_cell(raw)
449 # Match ignoring trailing whitespace
451 # Match ignoring trailing whitespace
450 self.assertEqual(out.rstrip(), out_t.rstrip())
452 self.assertEqual(out.rstrip(), out_t.rstrip())
451
453
452 def test_cellmagic_preempt(self):
454 def test_cellmagic_preempt(self):
453 isp = self.isp
455 isp = self.isp
454 for raw, name, line, cell in [
456 for raw, name, line, cell in [
455 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
457 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
456 ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'),
458 ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'),
457 (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'),
459 (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'),
458 ("%%cellm \n>>>hi", u'cellm', u'', u'hi'),
460 ("%%cellm \n>>>hi", u'cellm', u'', u'hi'),
459 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
461 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
460 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
462 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
461 ]:
463 ]:
462 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
464 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
463 name, line, cell
465 name, line, cell
464 )
466 )
465 out = isp.transform_cell(raw)
467 out = isp.transform_cell(raw)
466 self.assertEqual(out.rstrip(), expected.rstrip())
468 self.assertEqual(out.rstrip(), expected.rstrip())
467
469
468
470
469
471
470 #-----------------------------------------------------------------------------
472 #-----------------------------------------------------------------------------
471 # Main - use as a script, mostly for developer experiments
473 # Main - use as a script, mostly for developer experiments
472 #-----------------------------------------------------------------------------
474 #-----------------------------------------------------------------------------
473
475
474 if __name__ == '__main__':
476 if __name__ == '__main__':
475 # A simple demo for interactive experimentation. This code will not get
477 # A simple demo for interactive experimentation. This code will not get
476 # picked up by any test suite.
478 # picked up by any test suite.
477 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
479 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
478
480
479 # configure here the syntax to use, prompt and whether to autoindent
481 # configure here the syntax to use, prompt and whether to autoindent
480 #isp, start_prompt = InputSplitter(), '>>> '
482 #isp, start_prompt = InputSplitter(), '>>> '
481 isp, start_prompt = IPythonInputSplitter(), 'In> '
483 isp, start_prompt = IPythonInputSplitter(), 'In> '
482
484
483 autoindent = True
485 autoindent = True
484 #autoindent = False
486 #autoindent = False
485
487
486 try:
488 try:
487 while True:
489 while True:
488 prompt = start_prompt
490 prompt = start_prompt
489 while isp.push_accepts_more():
491 while isp.push_accepts_more():
490 indent = ' '*isp.indent_spaces
492 indent = ' '*isp.indent_spaces
491 if autoindent:
493 if autoindent:
492 line = indent + input(prompt+indent)
494 line = indent + input(prompt+indent)
493 else:
495 else:
494 line = input(prompt)
496 line = input(prompt)
495 isp.push(line)
497 isp.push(line)
496 prompt = '... '
498 prompt = '... '
497
499
498 # Here we just return input so we can use it in a test suite, but a
500 # Here we just return input so we can use it in a test suite, but a
499 # real interpreter would instead send it for execution somewhere.
501 # real interpreter would instead send it for execution somewhere.
500 #src = isp.source; raise EOFError # dbg
502 #src = isp.source; raise EOFError # dbg
501 src, raw = isp.source_raw_reset()
503 raw = isp.source_raw
504 src = isp.source_reset()
502 print('Input source was:\n', src)
505 print('Input source was:\n', src)
503 print('Raw source was:\n', raw)
506 print('Raw source was:\n', raw)
504 except EOFError:
507 except EOFError:
505 print('Bye')
508 print('Bye')
506
509
507 # Tests for cell magics support
510 # Tests for cell magics support
508
511
509 def test_last_blank():
512 def test_last_blank():
510 nt.assert_false(isp.last_blank(''))
513 nt.assert_false(isp.last_blank(''))
511 nt.assert_false(isp.last_blank('abc'))
514 nt.assert_false(isp.last_blank('abc'))
512 nt.assert_false(isp.last_blank('abc\n'))
515 nt.assert_false(isp.last_blank('abc\n'))
513 nt.assert_false(isp.last_blank('abc\na'))
516 nt.assert_false(isp.last_blank('abc\na'))
514
517
515 nt.assert_true(isp.last_blank('\n'))
518 nt.assert_true(isp.last_blank('\n'))
516 nt.assert_true(isp.last_blank('\n '))
519 nt.assert_true(isp.last_blank('\n '))
517 nt.assert_true(isp.last_blank('abc\n '))
520 nt.assert_true(isp.last_blank('abc\n '))
518 nt.assert_true(isp.last_blank('abc\n\n'))
521 nt.assert_true(isp.last_blank('abc\n\n'))
519 nt.assert_true(isp.last_blank('abc\nd\n\n'))
522 nt.assert_true(isp.last_blank('abc\nd\n\n'))
520 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
523 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
521 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
524 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
522
525
523
526
524 def test_last_two_blanks():
527 def test_last_two_blanks():
525 nt.assert_false(isp.last_two_blanks(''))
528 nt.assert_false(isp.last_two_blanks(''))
526 nt.assert_false(isp.last_two_blanks('abc'))
529 nt.assert_false(isp.last_two_blanks('abc'))
527 nt.assert_false(isp.last_two_blanks('abc\n'))
530 nt.assert_false(isp.last_two_blanks('abc\n'))
528 nt.assert_false(isp.last_two_blanks('abc\n\na'))
531 nt.assert_false(isp.last_two_blanks('abc\n\na'))
529 nt.assert_false(isp.last_two_blanks('abc\n \n'))
532 nt.assert_false(isp.last_two_blanks('abc\n \n'))
530 nt.assert_false(isp.last_two_blanks('abc\n\n'))
533 nt.assert_false(isp.last_two_blanks('abc\n\n'))
531
534
532 nt.assert_true(isp.last_two_blanks('\n\n'))
535 nt.assert_true(isp.last_two_blanks('\n\n'))
533 nt.assert_true(isp.last_two_blanks('\n\n '))
536 nt.assert_true(isp.last_two_blanks('\n\n '))
534 nt.assert_true(isp.last_two_blanks('\n \n'))
537 nt.assert_true(isp.last_two_blanks('\n \n'))
535 nt.assert_true(isp.last_two_blanks('abc\n\n '))
538 nt.assert_true(isp.last_two_blanks('abc\n\n '))
536 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
539 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
537 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
540 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
538 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
541 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
539 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
542 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
540 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
543 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
541 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
544 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
542
545
543
546
544 class CellMagicsCommon(object):
547 class CellMagicsCommon(object):
545
548
546 def test_whole_cell(self):
549 def test_whole_cell(self):
547 src = "%%cellm line\nbody\n"
550 src = "%%cellm line\nbody\n"
548 sp = self.sp
551 out = self.sp.transform_cell(src)
549 sp.push(src)
550 out = sp.source_reset()
551 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
552 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
552 nt.assert_equal(out, py3compat.u_format(ref))
553 nt.assert_equal(out, py3compat.u_format(ref))
553
554
554 def test_cellmagic_help(self):
555 def test_cellmagic_help(self):
555 self.sp.push('%%cellm?')
556 self.sp.push('%%cellm?')
556 nt.assert_false(self.sp.push_accepts_more())
557 nt.assert_false(self.sp.push_accepts_more())
557
558
558 def tearDown(self):
559 def tearDown(self):
559 self.sp.reset()
560 self.sp.reset()
560
561
561
562
562 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
563 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
563 sp = isp.IPythonInputSplitter(line_input_checker=False)
564 sp = isp.IPythonInputSplitter(line_input_checker=False)
564
565
565 def test_incremental(self):
566 def test_incremental(self):
566 sp = self.sp
567 sp = self.sp
567 sp.push('%%cellm firstline\n')
568 sp.push('%%cellm firstline\n')
568 nt.assert_true(sp.push_accepts_more()) #1
569 nt.assert_true(sp.push_accepts_more()) #1
569 sp.push('line2\n')
570 sp.push('line2\n')
570 nt.assert_true(sp.push_accepts_more()) #2
571 nt.assert_true(sp.push_accepts_more()) #2
571 sp.push('\n')
572 sp.push('\n')
572 # This should accept a blank line and carry on until the cell is reset
573 # This should accept a blank line and carry on until the cell is reset
573 nt.assert_true(sp.push_accepts_more()) #3
574 nt.assert_true(sp.push_accepts_more()) #3
574
575
575 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
576 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
576 sp = isp.IPythonInputSplitter(line_input_checker=True)
577 sp = isp.IPythonInputSplitter(line_input_checker=True)
577
578
578 def test_incremental(self):
579 def test_incremental(self):
579 sp = self.sp
580 sp = self.sp
580 sp.push('%%cellm line2\n')
581 sp.push('%%cellm line2\n')
581 nt.assert_true(sp.push_accepts_more()) #1
582 nt.assert_true(sp.push_accepts_more()) #1
582 sp.push('\n')
583 sp.push('\n')
583 # In this case, a blank line should end the cell magic
584 # In this case, a blank line should end the cell magic
584 nt.assert_false(sp.push_accepts_more()) #2
585 nt.assert_false(sp.push_accepts_more()) #2
@@ -1,677 +1,715 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the key interactiveshell module.
2 """Tests for the key interactiveshell module.
3
3
4 Historically the main classes in interactiveshell have been under-tested. This
4 Historically the main classes in interactiveshell have been under-tested. This
5 module should grow as many single-method tests as possible to trap many of the
5 module should grow as many single-method tests as possible to trap many of the
6 recurring bugs we seem to encounter with high-level interaction.
6 recurring bugs we seem to encounter with high-level interaction.
7
7
8 Authors
8 Authors
9 -------
9 -------
10 * Fernando Perez
10 * Fernando Perez
11 """
11 """
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2011 The IPython Development Team
13 # Copyright (C) 2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # stdlib
22 # stdlib
23 import ast
23 import ast
24 import os
24 import os
25 import signal
25 import signal
26 import shutil
26 import shutil
27 import sys
27 import sys
28 import tempfile
28 import tempfile
29 import unittest
29 import unittest
30 from os.path import join
30 from os.path import join
31
31
32 # third-party
32 # third-party
33 import nose.tools as nt
33 import nose.tools as nt
34
34
35 # Our own
35 # Our own
36 from IPython.core.inputtransformer import InputTransformer
36 from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths
37 from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths
37 from IPython.testing import tools as tt
38 from IPython.testing import tools as tt
38 from IPython.utils import io
39 from IPython.utils import io
39 from IPython.utils import py3compat
40 from IPython.utils import py3compat
40 from IPython.utils.py3compat import unicode_type, PY3
41 from IPython.utils.py3compat import unicode_type, PY3
41
42
42 if PY3:
43 if PY3:
43 from io import StringIO
44 from io import StringIO
44 else:
45 else:
45 from StringIO import StringIO
46 from StringIO import StringIO
46
47
47 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
48 # Globals
49 # Globals
49 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
50 # This is used by every single test, no point repeating it ad nauseam
51 # This is used by every single test, no point repeating it ad nauseam
51 ip = get_ipython()
52 ip = get_ipython()
52
53
53 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
54 # Tests
55 # Tests
55 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
56
57
57 class InteractiveShellTestCase(unittest.TestCase):
58 class InteractiveShellTestCase(unittest.TestCase):
58 def test_naked_string_cells(self):
59 def test_naked_string_cells(self):
59 """Test that cells with only naked strings are fully executed"""
60 """Test that cells with only naked strings are fully executed"""
60 # First, single-line inputs
61 # First, single-line inputs
61 ip.run_cell('"a"\n')
62 ip.run_cell('"a"\n')
62 self.assertEqual(ip.user_ns['_'], 'a')
63 self.assertEqual(ip.user_ns['_'], 'a')
63 # And also multi-line cells
64 # And also multi-line cells
64 ip.run_cell('"""a\nb"""\n')
65 ip.run_cell('"""a\nb"""\n')
65 self.assertEqual(ip.user_ns['_'], 'a\nb')
66 self.assertEqual(ip.user_ns['_'], 'a\nb')
66
67
67 def test_run_empty_cell(self):
68 def test_run_empty_cell(self):
68 """Just make sure we don't get a horrible error with a blank
69 """Just make sure we don't get a horrible error with a blank
69 cell of input. Yes, I did overlook that."""
70 cell of input. Yes, I did overlook that."""
70 old_xc = ip.execution_count
71 old_xc = ip.execution_count
71 ip.run_cell('')
72 ip.run_cell('')
72 self.assertEqual(ip.execution_count, old_xc)
73 self.assertEqual(ip.execution_count, old_xc)
73
74
74 def test_run_cell_multiline(self):
75 def test_run_cell_multiline(self):
75 """Multi-block, multi-line cells must execute correctly.
76 """Multi-block, multi-line cells must execute correctly.
76 """
77 """
77 src = '\n'.join(["x=1",
78 src = '\n'.join(["x=1",
78 "y=2",
79 "y=2",
79 "if 1:",
80 "if 1:",
80 " x += 1",
81 " x += 1",
81 " y += 1",])
82 " y += 1",])
82 ip.run_cell(src)
83 ip.run_cell(src)
83 self.assertEqual(ip.user_ns['x'], 2)
84 self.assertEqual(ip.user_ns['x'], 2)
84 self.assertEqual(ip.user_ns['y'], 3)
85 self.assertEqual(ip.user_ns['y'], 3)
85
86
86 def test_multiline_string_cells(self):
87 def test_multiline_string_cells(self):
87 "Code sprinkled with multiline strings should execute (GH-306)"
88 "Code sprinkled with multiline strings should execute (GH-306)"
88 ip.run_cell('tmp=0')
89 ip.run_cell('tmp=0')
89 self.assertEqual(ip.user_ns['tmp'], 0)
90 self.assertEqual(ip.user_ns['tmp'], 0)
90 ip.run_cell('tmp=1;"""a\nb"""\n')
91 ip.run_cell('tmp=1;"""a\nb"""\n')
91 self.assertEqual(ip.user_ns['tmp'], 1)
92 self.assertEqual(ip.user_ns['tmp'], 1)
92
93
93 def test_dont_cache_with_semicolon(self):
94 def test_dont_cache_with_semicolon(self):
94 "Ending a line with semicolon should not cache the returned object (GH-307)"
95 "Ending a line with semicolon should not cache the returned object (GH-307)"
95 oldlen = len(ip.user_ns['Out'])
96 oldlen = len(ip.user_ns['Out'])
96 a = ip.run_cell('1;', store_history=True)
97 a = ip.run_cell('1;', store_history=True)
97 newlen = len(ip.user_ns['Out'])
98 newlen = len(ip.user_ns['Out'])
98 self.assertEqual(oldlen, newlen)
99 self.assertEqual(oldlen, newlen)
99 #also test the default caching behavior
100 #also test the default caching behavior
100 ip.run_cell('1', store_history=True)
101 ip.run_cell('1', store_history=True)
101 newlen = len(ip.user_ns['Out'])
102 newlen = len(ip.user_ns['Out'])
102 self.assertEqual(oldlen+1, newlen)
103 self.assertEqual(oldlen+1, newlen)
103
104
104 def test_In_variable(self):
105 def test_In_variable(self):
105 "Verify that In variable grows with user input (GH-284)"
106 "Verify that In variable grows with user input (GH-284)"
106 oldlen = len(ip.user_ns['In'])
107 oldlen = len(ip.user_ns['In'])
107 ip.run_cell('1;', store_history=True)
108 ip.run_cell('1;', store_history=True)
108 newlen = len(ip.user_ns['In'])
109 newlen = len(ip.user_ns['In'])
109 self.assertEqual(oldlen+1, newlen)
110 self.assertEqual(oldlen+1, newlen)
110 self.assertEqual(ip.user_ns['In'][-1],'1;')
111 self.assertEqual(ip.user_ns['In'][-1],'1;')
111
112
112 def test_magic_names_in_string(self):
113 def test_magic_names_in_string(self):
113 ip.run_cell('a = """\n%exit\n"""')
114 ip.run_cell('a = """\n%exit\n"""')
114 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
115 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
115
116
116 def test_trailing_newline(self):
117 def test_trailing_newline(self):
117 """test that running !(command) does not raise a SyntaxError"""
118 """test that running !(command) does not raise a SyntaxError"""
118 ip.run_cell('!(true)\n', False)
119 ip.run_cell('!(true)\n', False)
119 ip.run_cell('!(true)\n\n\n', False)
120 ip.run_cell('!(true)\n\n\n', False)
120
121
121 def test_gh_597(self):
122 def test_gh_597(self):
122 """Pretty-printing lists of objects with non-ascii reprs may cause
123 """Pretty-printing lists of objects with non-ascii reprs may cause
123 problems."""
124 problems."""
124 class Spam(object):
125 class Spam(object):
125 def __repr__(self):
126 def __repr__(self):
126 return "\xe9"*50
127 return "\xe9"*50
127 import IPython.core.formatters
128 import IPython.core.formatters
128 f = IPython.core.formatters.PlainTextFormatter()
129 f = IPython.core.formatters.PlainTextFormatter()
129 f([Spam(),Spam()])
130 f([Spam(),Spam()])
130
131
131
132
132 def test_future_flags(self):
133 def test_future_flags(self):
133 """Check that future flags are used for parsing code (gh-777)"""
134 """Check that future flags are used for parsing code (gh-777)"""
134 ip.run_cell('from __future__ import print_function')
135 ip.run_cell('from __future__ import print_function')
135 try:
136 try:
136 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
137 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
137 assert 'prfunc_return_val' in ip.user_ns
138 assert 'prfunc_return_val' in ip.user_ns
138 finally:
139 finally:
139 # Reset compiler flags so we don't mess up other tests.
140 # Reset compiler flags so we don't mess up other tests.
140 ip.compile.reset_compiler_flags()
141 ip.compile.reset_compiler_flags()
141
142
142 def test_future_unicode(self):
143 def test_future_unicode(self):
143 """Check that unicode_literals is imported from __future__ (gh #786)"""
144 """Check that unicode_literals is imported from __future__ (gh #786)"""
144 try:
145 try:
145 ip.run_cell(u'byte_str = "a"')
146 ip.run_cell(u'byte_str = "a"')
146 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
147 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
147 ip.run_cell('from __future__ import unicode_literals')
148 ip.run_cell('from __future__ import unicode_literals')
148 ip.run_cell(u'unicode_str = "a"')
149 ip.run_cell(u'unicode_str = "a"')
149 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
150 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
150 finally:
151 finally:
151 # Reset compiler flags so we don't mess up other tests.
152 # Reset compiler flags so we don't mess up other tests.
152 ip.compile.reset_compiler_flags()
153 ip.compile.reset_compiler_flags()
153
154
154 def test_can_pickle(self):
155 def test_can_pickle(self):
155 "Can we pickle objects defined interactively (GH-29)"
156 "Can we pickle objects defined interactively (GH-29)"
156 ip = get_ipython()
157 ip = get_ipython()
157 ip.reset()
158 ip.reset()
158 ip.run_cell(("class Mylist(list):\n"
159 ip.run_cell(("class Mylist(list):\n"
159 " def __init__(self,x=[]):\n"
160 " def __init__(self,x=[]):\n"
160 " list.__init__(self,x)"))
161 " list.__init__(self,x)"))
161 ip.run_cell("w=Mylist([1,2,3])")
162 ip.run_cell("w=Mylist([1,2,3])")
162
163
163 from pickle import dumps
164 from pickle import dumps
164
165
165 # We need to swap in our main module - this is only necessary
166 # We need to swap in our main module - this is only necessary
166 # inside the test framework, because IPython puts the interactive module
167 # inside the test framework, because IPython puts the interactive module
167 # in place (but the test framework undoes this).
168 # in place (but the test framework undoes this).
168 _main = sys.modules['__main__']
169 _main = sys.modules['__main__']
169 sys.modules['__main__'] = ip.user_module
170 sys.modules['__main__'] = ip.user_module
170 try:
171 try:
171 res = dumps(ip.user_ns["w"])
172 res = dumps(ip.user_ns["w"])
172 finally:
173 finally:
173 sys.modules['__main__'] = _main
174 sys.modules['__main__'] = _main
174 self.assertTrue(isinstance(res, bytes))
175 self.assertTrue(isinstance(res, bytes))
175
176
176 def test_global_ns(self):
177 def test_global_ns(self):
177 "Code in functions must be able to access variables outside them."
178 "Code in functions must be able to access variables outside them."
178 ip = get_ipython()
179 ip = get_ipython()
179 ip.run_cell("a = 10")
180 ip.run_cell("a = 10")
180 ip.run_cell(("def f(x):\n"
181 ip.run_cell(("def f(x):\n"
181 " return x + a"))
182 " return x + a"))
182 ip.run_cell("b = f(12)")
183 ip.run_cell("b = f(12)")
183 self.assertEqual(ip.user_ns["b"], 22)
184 self.assertEqual(ip.user_ns["b"], 22)
184
185
185 def test_bad_custom_tb(self):
186 def test_bad_custom_tb(self):
186 """Check that InteractiveShell is protected from bad custom exception handlers"""
187 """Check that InteractiveShell is protected from bad custom exception handlers"""
187 from IPython.utils import io
188 from IPython.utils import io
188 save_stderr = io.stderr
189 save_stderr = io.stderr
189 try:
190 try:
190 # capture stderr
191 # capture stderr
191 io.stderr = StringIO()
192 io.stderr = StringIO()
192 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
193 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
193 self.assertEqual(ip.custom_exceptions, (IOError,))
194 self.assertEqual(ip.custom_exceptions, (IOError,))
194 ip.run_cell(u'raise IOError("foo")')
195 ip.run_cell(u'raise IOError("foo")')
195 self.assertEqual(ip.custom_exceptions, ())
196 self.assertEqual(ip.custom_exceptions, ())
196 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
197 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
197 finally:
198 finally:
198 io.stderr = save_stderr
199 io.stderr = save_stderr
199
200
200 def test_bad_custom_tb_return(self):
201 def test_bad_custom_tb_return(self):
201 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
202 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
202 from IPython.utils import io
203 from IPython.utils import io
203 save_stderr = io.stderr
204 save_stderr = io.stderr
204 try:
205 try:
205 # capture stderr
206 # capture stderr
206 io.stderr = StringIO()
207 io.stderr = StringIO()
207 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
208 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
208 self.assertEqual(ip.custom_exceptions, (NameError,))
209 self.assertEqual(ip.custom_exceptions, (NameError,))
209 ip.run_cell(u'a=abracadabra')
210 ip.run_cell(u'a=abracadabra')
210 self.assertEqual(ip.custom_exceptions, ())
211 self.assertEqual(ip.custom_exceptions, ())
211 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
212 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
212 finally:
213 finally:
213 io.stderr = save_stderr
214 io.stderr = save_stderr
214
215
215 def test_drop_by_id(self):
216 def test_drop_by_id(self):
216 myvars = {"a":object(), "b":object(), "c": object()}
217 myvars = {"a":object(), "b":object(), "c": object()}
217 ip.push(myvars, interactive=False)
218 ip.push(myvars, interactive=False)
218 for name in myvars:
219 for name in myvars:
219 assert name in ip.user_ns, name
220 assert name in ip.user_ns, name
220 assert name in ip.user_ns_hidden, name
221 assert name in ip.user_ns_hidden, name
221 ip.user_ns['b'] = 12
222 ip.user_ns['b'] = 12
222 ip.drop_by_id(myvars)
223 ip.drop_by_id(myvars)
223 for name in ["a", "c"]:
224 for name in ["a", "c"]:
224 assert name not in ip.user_ns, name
225 assert name not in ip.user_ns, name
225 assert name not in ip.user_ns_hidden, name
226 assert name not in ip.user_ns_hidden, name
226 assert ip.user_ns['b'] == 12
227 assert ip.user_ns['b'] == 12
227 ip.reset()
228 ip.reset()
228
229
229 def test_var_expand(self):
230 def test_var_expand(self):
230 ip.user_ns['f'] = u'Ca\xf1o'
231 ip.user_ns['f'] = u'Ca\xf1o'
231 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
232 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
232 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
233 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
233 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
234 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
234 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
235 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
235
236
236 ip.user_ns['f'] = b'Ca\xc3\xb1o'
237 ip.user_ns['f'] = b'Ca\xc3\xb1o'
237 # This should not raise any exception:
238 # This should not raise any exception:
238 ip.var_expand(u'echo $f')
239 ip.var_expand(u'echo $f')
239
240
240 def test_var_expand_local(self):
241 def test_var_expand_local(self):
241 """Test local variable expansion in !system and %magic calls"""
242 """Test local variable expansion in !system and %magic calls"""
242 # !system
243 # !system
243 ip.run_cell('def test():\n'
244 ip.run_cell('def test():\n'
244 ' lvar = "ttt"\n'
245 ' lvar = "ttt"\n'
245 ' ret = !echo {lvar}\n'
246 ' ret = !echo {lvar}\n'
246 ' return ret[0]\n')
247 ' return ret[0]\n')
247 res = ip.user_ns['test']()
248 res = ip.user_ns['test']()
248 nt.assert_in('ttt', res)
249 nt.assert_in('ttt', res)
249
250
250 # %magic
251 # %magic
251 ip.run_cell('def makemacro():\n'
252 ip.run_cell('def makemacro():\n'
252 ' macroname = "macro_var_expand_locals"\n'
253 ' macroname = "macro_var_expand_locals"\n'
253 ' %macro {macroname} codestr\n')
254 ' %macro {macroname} codestr\n')
254 ip.user_ns['codestr'] = "str(12)"
255 ip.user_ns['codestr'] = "str(12)"
255 ip.run_cell('makemacro()')
256 ip.run_cell('makemacro()')
256 nt.assert_in('macro_var_expand_locals', ip.user_ns)
257 nt.assert_in('macro_var_expand_locals', ip.user_ns)
257
258
258 def test_var_expand_self(self):
259 def test_var_expand_self(self):
259 """Test variable expansion with the name 'self', which was failing.
260 """Test variable expansion with the name 'self', which was failing.
260
261
261 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
262 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
262 """
263 """
263 ip.run_cell('class cTest:\n'
264 ip.run_cell('class cTest:\n'
264 ' classvar="see me"\n'
265 ' classvar="see me"\n'
265 ' def test(self):\n'
266 ' def test(self):\n'
266 ' res = !echo Variable: {self.classvar}\n'
267 ' res = !echo Variable: {self.classvar}\n'
267 ' return res[0]\n')
268 ' return res[0]\n')
268 nt.assert_in('see me', ip.user_ns['cTest']().test())
269 nt.assert_in('see me', ip.user_ns['cTest']().test())
269
270
270 def test_bad_var_expand(self):
271 def test_bad_var_expand(self):
271 """var_expand on invalid formats shouldn't raise"""
272 """var_expand on invalid formats shouldn't raise"""
272 # SyntaxError
273 # SyntaxError
273 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
274 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
274 # NameError
275 # NameError
275 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
276 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
276 # ZeroDivisionError
277 # ZeroDivisionError
277 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
278 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
278
279
279 def test_silent_nopostexec(self):
280 def test_silent_nopostexec(self):
280 """run_cell(silent=True) doesn't invoke post-exec funcs"""
281 """run_cell(silent=True) doesn't invoke post-exec funcs"""
281 d = dict(called=False)
282 d = dict(called=False)
282 def set_called():
283 def set_called():
283 d['called'] = True
284 d['called'] = True
284
285
285 ip.register_post_execute(set_called)
286 ip.register_post_execute(set_called)
286 ip.run_cell("1", silent=True)
287 ip.run_cell("1", silent=True)
287 self.assertFalse(d['called'])
288 self.assertFalse(d['called'])
288 # double-check that non-silent exec did what we expected
289 # double-check that non-silent exec did what we expected
289 # silent to avoid
290 # silent to avoid
290 ip.run_cell("1")
291 ip.run_cell("1")
291 self.assertTrue(d['called'])
292 self.assertTrue(d['called'])
292 # remove post-exec
293 # remove post-exec
293 ip._post_execute.pop(set_called)
294 ip._post_execute.pop(set_called)
294
295
295 def test_silent_noadvance(self):
296 def test_silent_noadvance(self):
296 """run_cell(silent=True) doesn't advance execution_count"""
297 """run_cell(silent=True) doesn't advance execution_count"""
297 ec = ip.execution_count
298 ec = ip.execution_count
298 # silent should force store_history=False
299 # silent should force store_history=False
299 ip.run_cell("1", store_history=True, silent=True)
300 ip.run_cell("1", store_history=True, silent=True)
300
301
301 self.assertEqual(ec, ip.execution_count)
302 self.assertEqual(ec, ip.execution_count)
302 # double-check that non-silent exec did what we expected
303 # double-check that non-silent exec did what we expected
303 # silent to avoid
304 # silent to avoid
304 ip.run_cell("1", store_history=True)
305 ip.run_cell("1", store_history=True)
305 self.assertEqual(ec+1, ip.execution_count)
306 self.assertEqual(ec+1, ip.execution_count)
306
307
307 def test_silent_nodisplayhook(self):
308 def test_silent_nodisplayhook(self):
308 """run_cell(silent=True) doesn't trigger displayhook"""
309 """run_cell(silent=True) doesn't trigger displayhook"""
309 d = dict(called=False)
310 d = dict(called=False)
310
311
311 trap = ip.display_trap
312 trap = ip.display_trap
312 save_hook = trap.hook
313 save_hook = trap.hook
313
314
314 def failing_hook(*args, **kwargs):
315 def failing_hook(*args, **kwargs):
315 d['called'] = True
316 d['called'] = True
316
317
317 try:
318 try:
318 trap.hook = failing_hook
319 trap.hook = failing_hook
319 ip.run_cell("1", silent=True)
320 ip.run_cell("1", silent=True)
320 self.assertFalse(d['called'])
321 self.assertFalse(d['called'])
321 # double-check that non-silent exec did what we expected
322 # double-check that non-silent exec did what we expected
322 # silent to avoid
323 # silent to avoid
323 ip.run_cell("1")
324 ip.run_cell("1")
324 self.assertTrue(d['called'])
325 self.assertTrue(d['called'])
325 finally:
326 finally:
326 trap.hook = save_hook
327 trap.hook = save_hook
327
328
328 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
329 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
329 def test_print_softspace(self):
330 def test_print_softspace(self):
330 """Verify that softspace is handled correctly when executing multiple
331 """Verify that softspace is handled correctly when executing multiple
331 statements.
332 statements.
332
333
333 In [1]: print 1; print 2
334 In [1]: print 1; print 2
334 1
335 1
335 2
336 2
336
337
337 In [2]: print 1,; print 2
338 In [2]: print 1,; print 2
338 1 2
339 1 2
339 """
340 """
340
341
341 def test_ofind_line_magic(self):
342 def test_ofind_line_magic(self):
342 from IPython.core.magic import register_line_magic
343 from IPython.core.magic import register_line_magic
343
344
344 @register_line_magic
345 @register_line_magic
345 def lmagic(line):
346 def lmagic(line):
346 "A line magic"
347 "A line magic"
347
348
348 # Get info on line magic
349 # Get info on line magic
349 lfind = ip._ofind('lmagic')
350 lfind = ip._ofind('lmagic')
350 info = dict(found=True, isalias=False, ismagic=True,
351 info = dict(found=True, isalias=False, ismagic=True,
351 namespace = 'IPython internal', obj= lmagic.__wrapped__,
352 namespace = 'IPython internal', obj= lmagic.__wrapped__,
352 parent = None)
353 parent = None)
353 nt.assert_equal(lfind, info)
354 nt.assert_equal(lfind, info)
354
355
355 def test_ofind_cell_magic(self):
356 def test_ofind_cell_magic(self):
356 from IPython.core.magic import register_cell_magic
357 from IPython.core.magic import register_cell_magic
357
358
358 @register_cell_magic
359 @register_cell_magic
359 def cmagic(line, cell):
360 def cmagic(line, cell):
360 "A cell magic"
361 "A cell magic"
361
362
362 # Get info on cell magic
363 # Get info on cell magic
363 find = ip._ofind('cmagic')
364 find = ip._ofind('cmagic')
364 info = dict(found=True, isalias=False, ismagic=True,
365 info = dict(found=True, isalias=False, ismagic=True,
365 namespace = 'IPython internal', obj= cmagic.__wrapped__,
366 namespace = 'IPython internal', obj= cmagic.__wrapped__,
366 parent = None)
367 parent = None)
367 nt.assert_equal(find, info)
368 nt.assert_equal(find, info)
368
369
369 def test_custom_exception(self):
370 def test_custom_exception(self):
370 called = []
371 called = []
371 def my_handler(shell, etype, value, tb, tb_offset=None):
372 def my_handler(shell, etype, value, tb, tb_offset=None):
372 called.append(etype)
373 called.append(etype)
373 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
374 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
374
375
375 ip.set_custom_exc((ValueError,), my_handler)
376 ip.set_custom_exc((ValueError,), my_handler)
376 try:
377 try:
377 ip.run_cell("raise ValueError('test')")
378 ip.run_cell("raise ValueError('test')")
378 # Check that this was called, and only once.
379 # Check that this was called, and only once.
379 self.assertEqual(called, [ValueError])
380 self.assertEqual(called, [ValueError])
380 finally:
381 finally:
381 # Reset the custom exception hook
382 # Reset the custom exception hook
382 ip.set_custom_exc((), None)
383 ip.set_custom_exc((), None)
383
384
384 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
385 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
385 def test_future_environment(self):
386 def test_future_environment(self):
386 "Can we run code with & without the shell's __future__ imports?"
387 "Can we run code with & without the shell's __future__ imports?"
387 ip.run_cell("from __future__ import division")
388 ip.run_cell("from __future__ import division")
388 ip.run_cell("a = 1/2", shell_futures=True)
389 ip.run_cell("a = 1/2", shell_futures=True)
389 self.assertEqual(ip.user_ns['a'], 0.5)
390 self.assertEqual(ip.user_ns['a'], 0.5)
390 ip.run_cell("b = 1/2", shell_futures=False)
391 ip.run_cell("b = 1/2", shell_futures=False)
391 self.assertEqual(ip.user_ns['b'], 0)
392 self.assertEqual(ip.user_ns['b'], 0)
392
393
393 ip.compile.reset_compiler_flags()
394 ip.compile.reset_compiler_flags()
394 # This shouldn't leak to the shell's compiler
395 # This shouldn't leak to the shell's compiler
395 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
396 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
396 self.assertEqual(ip.user_ns['c'], 0.5)
397 self.assertEqual(ip.user_ns['c'], 0.5)
397 ip.run_cell("d = 1/2", shell_futures=True)
398 ip.run_cell("d = 1/2", shell_futures=True)
398 self.assertEqual(ip.user_ns['d'], 0)
399 self.assertEqual(ip.user_ns['d'], 0)
399
400
400
401
401 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
402 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
402
403
403 @onlyif_unicode_paths
404 @onlyif_unicode_paths
404 def setUp(self):
405 def setUp(self):
405 self.BASETESTDIR = tempfile.mkdtemp()
406 self.BASETESTDIR = tempfile.mkdtemp()
406 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
407 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
407 os.mkdir(self.TESTDIR)
408 os.mkdir(self.TESTDIR)
408 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
409 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
409 sfile.write("pass\n")
410 sfile.write("pass\n")
410 self.oldpath = py3compat.getcwd()
411 self.oldpath = py3compat.getcwd()
411 os.chdir(self.TESTDIR)
412 os.chdir(self.TESTDIR)
412 self.fname = u"Γ₯Àâtestscript.py"
413 self.fname = u"Γ₯Àâtestscript.py"
413
414
414 def tearDown(self):
415 def tearDown(self):
415 os.chdir(self.oldpath)
416 os.chdir(self.oldpath)
416 shutil.rmtree(self.BASETESTDIR)
417 shutil.rmtree(self.BASETESTDIR)
417
418
418 @onlyif_unicode_paths
419 @onlyif_unicode_paths
419 def test_1(self):
420 def test_1(self):
420 """Test safe_execfile with non-ascii path
421 """Test safe_execfile with non-ascii path
421 """
422 """
422 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
423 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
423
424
424 class ExitCodeChecks(tt.TempFileMixin):
425 class ExitCodeChecks(tt.TempFileMixin):
425 def test_exit_code_ok(self):
426 def test_exit_code_ok(self):
426 self.system('exit 0')
427 self.system('exit 0')
427 self.assertEqual(ip.user_ns['_exit_code'], 0)
428 self.assertEqual(ip.user_ns['_exit_code'], 0)
428
429
429 def test_exit_code_error(self):
430 def test_exit_code_error(self):
430 self.system('exit 1')
431 self.system('exit 1')
431 self.assertEqual(ip.user_ns['_exit_code'], 1)
432 self.assertEqual(ip.user_ns['_exit_code'], 1)
432
433
433 @skipif(not hasattr(signal, 'SIGALRM'))
434 @skipif(not hasattr(signal, 'SIGALRM'))
434 def test_exit_code_signal(self):
435 def test_exit_code_signal(self):
435 self.mktmp("import signal, time\n"
436 self.mktmp("import signal, time\n"
436 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
437 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
437 "time.sleep(1)\n")
438 "time.sleep(1)\n")
438 self.system("%s %s" % (sys.executable, self.fname))
439 self.system("%s %s" % (sys.executable, self.fname))
439 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
440 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
440
441
441 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
442 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
442 system = ip.system_raw
443 system = ip.system_raw
443
444
444 @onlyif_unicode_paths
445 @onlyif_unicode_paths
445 def test_1(self):
446 def test_1(self):
446 """Test system_raw with non-ascii cmd
447 """Test system_raw with non-ascii cmd
447 """
448 """
448 cmd = u'''python -c "'Γ₯Àâ'" '''
449 cmd = u'''python -c "'Γ₯Àâ'" '''
449 ip.system_raw(cmd)
450 ip.system_raw(cmd)
450
451
451 # TODO: Exit codes are currently ignored on Windows.
452 # TODO: Exit codes are currently ignored on Windows.
452 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
453 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
453 system = ip.system_piped
454 system = ip.system_piped
454
455
455 @skip_win32
456 @skip_win32
456 def test_exit_code_ok(self):
457 def test_exit_code_ok(self):
457 ExitCodeChecks.test_exit_code_ok(self)
458 ExitCodeChecks.test_exit_code_ok(self)
458
459
459 @skip_win32
460 @skip_win32
460 def test_exit_code_error(self):
461 def test_exit_code_error(self):
461 ExitCodeChecks.test_exit_code_error(self)
462 ExitCodeChecks.test_exit_code_error(self)
462
463
463 @skip_win32
464 @skip_win32
464 def test_exit_code_signal(self):
465 def test_exit_code_signal(self):
465 ExitCodeChecks.test_exit_code_signal(self)
466 ExitCodeChecks.test_exit_code_signal(self)
466
467
467 class TestModules(unittest.TestCase, tt.TempFileMixin):
468 class TestModules(unittest.TestCase, tt.TempFileMixin):
468 def test_extraneous_loads(self):
469 def test_extraneous_loads(self):
469 """Test we're not loading modules on startup that we shouldn't.
470 """Test we're not loading modules on startup that we shouldn't.
470 """
471 """
471 self.mktmp("import sys\n"
472 self.mktmp("import sys\n"
472 "print('numpy' in sys.modules)\n"
473 "print('numpy' in sys.modules)\n"
473 "print('IPython.parallel' in sys.modules)\n"
474 "print('IPython.parallel' in sys.modules)\n"
474 "print('IPython.kernel.zmq' in sys.modules)\n"
475 "print('IPython.kernel.zmq' in sys.modules)\n"
475 )
476 )
476 out = "False\nFalse\nFalse\n"
477 out = "False\nFalse\nFalse\n"
477 tt.ipexec_validate(self.fname, out)
478 tt.ipexec_validate(self.fname, out)
478
479
479 class Negator(ast.NodeTransformer):
480 class Negator(ast.NodeTransformer):
480 """Negates all number literals in an AST."""
481 """Negates all number literals in an AST."""
481 def visit_Num(self, node):
482 def visit_Num(self, node):
482 node.n = -node.n
483 node.n = -node.n
483 return node
484 return node
484
485
485 class TestAstTransform(unittest.TestCase):
486 class TestAstTransform(unittest.TestCase):
486 def setUp(self):
487 def setUp(self):
487 self.negator = Negator()
488 self.negator = Negator()
488 ip.ast_transformers.append(self.negator)
489 ip.ast_transformers.append(self.negator)
489
490
490 def tearDown(self):
491 def tearDown(self):
491 ip.ast_transformers.remove(self.negator)
492 ip.ast_transformers.remove(self.negator)
492
493
493 def test_run_cell(self):
494 def test_run_cell(self):
494 with tt.AssertPrints('-34'):
495 with tt.AssertPrints('-34'):
495 ip.run_cell('print (12 + 22)')
496 ip.run_cell('print (12 + 22)')
496
497
497 # A named reference to a number shouldn't be transformed.
498 # A named reference to a number shouldn't be transformed.
498 ip.user_ns['n'] = 55
499 ip.user_ns['n'] = 55
499 with tt.AssertNotPrints('-55'):
500 with tt.AssertNotPrints('-55'):
500 ip.run_cell('print (n)')
501 ip.run_cell('print (n)')
501
502
502 def test_timeit(self):
503 def test_timeit(self):
503 called = set()
504 called = set()
504 def f(x):
505 def f(x):
505 called.add(x)
506 called.add(x)
506 ip.push({'f':f})
507 ip.push({'f':f})
507
508
508 with tt.AssertPrints("best of "):
509 with tt.AssertPrints("best of "):
509 ip.run_line_magic("timeit", "-n1 f(1)")
510 ip.run_line_magic("timeit", "-n1 f(1)")
510 self.assertEqual(called, set([-1]))
511 self.assertEqual(called, set([-1]))
511 called.clear()
512 called.clear()
512
513
513 with tt.AssertPrints("best of "):
514 with tt.AssertPrints("best of "):
514 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
515 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
515 self.assertEqual(called, set([-2, -3]))
516 self.assertEqual(called, set([-2, -3]))
516
517
517 def test_time(self):
518 def test_time(self):
518 called = []
519 called = []
519 def f(x):
520 def f(x):
520 called.append(x)
521 called.append(x)
521 ip.push({'f':f})
522 ip.push({'f':f})
522
523
523 # Test with an expression
524 # Test with an expression
524 with tt.AssertPrints("Wall time: "):
525 with tt.AssertPrints("Wall time: "):
525 ip.run_line_magic("time", "f(5+9)")
526 ip.run_line_magic("time", "f(5+9)")
526 self.assertEqual(called, [-14])
527 self.assertEqual(called, [-14])
527 called[:] = []
528 called[:] = []
528
529
529 # Test with a statement (different code path)
530 # Test with a statement (different code path)
530 with tt.AssertPrints("Wall time: "):
531 with tt.AssertPrints("Wall time: "):
531 ip.run_line_magic("time", "a = f(-3 + -2)")
532 ip.run_line_magic("time", "a = f(-3 + -2)")
532 self.assertEqual(called, [5])
533 self.assertEqual(called, [5])
533
534
534 def test_macro(self):
535 def test_macro(self):
535 ip.push({'a':10})
536 ip.push({'a':10})
536 # The AST transformation makes this do a+=-1
537 # The AST transformation makes this do a+=-1
537 ip.define_macro("amacro", "a+=1\nprint(a)")
538 ip.define_macro("amacro", "a+=1\nprint(a)")
538
539
539 with tt.AssertPrints("9"):
540 with tt.AssertPrints("9"):
540 ip.run_cell("amacro")
541 ip.run_cell("amacro")
541 with tt.AssertPrints("8"):
542 with tt.AssertPrints("8"):
542 ip.run_cell("amacro")
543 ip.run_cell("amacro")
543
544
544 class IntegerWrapper(ast.NodeTransformer):
545 class IntegerWrapper(ast.NodeTransformer):
545 """Wraps all integers in a call to Integer()"""
546 """Wraps all integers in a call to Integer()"""
546 def visit_Num(self, node):
547 def visit_Num(self, node):
547 if isinstance(node.n, int):
548 if isinstance(node.n, int):
548 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
549 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
549 args=[node], keywords=[])
550 args=[node], keywords=[])
550 return node
551 return node
551
552
552 class TestAstTransform2(unittest.TestCase):
553 class TestAstTransform2(unittest.TestCase):
553 def setUp(self):
554 def setUp(self):
554 self.intwrapper = IntegerWrapper()
555 self.intwrapper = IntegerWrapper()
555 ip.ast_transformers.append(self.intwrapper)
556 ip.ast_transformers.append(self.intwrapper)
556
557
557 self.calls = []
558 self.calls = []
558 def Integer(*args):
559 def Integer(*args):
559 self.calls.append(args)
560 self.calls.append(args)
560 return args
561 return args
561 ip.push({"Integer": Integer})
562 ip.push({"Integer": Integer})
562
563
563 def tearDown(self):
564 def tearDown(self):
564 ip.ast_transformers.remove(self.intwrapper)
565 ip.ast_transformers.remove(self.intwrapper)
565 del ip.user_ns['Integer']
566 del ip.user_ns['Integer']
566
567
567 def test_run_cell(self):
568 def test_run_cell(self):
568 ip.run_cell("n = 2")
569 ip.run_cell("n = 2")
569 self.assertEqual(self.calls, [(2,)])
570 self.assertEqual(self.calls, [(2,)])
570
571
571 # This shouldn't throw an error
572 # This shouldn't throw an error
572 ip.run_cell("o = 2.0")
573 ip.run_cell("o = 2.0")
573 self.assertEqual(ip.user_ns['o'], 2.0)
574 self.assertEqual(ip.user_ns['o'], 2.0)
574
575
575 def test_timeit(self):
576 def test_timeit(self):
576 called = set()
577 called = set()
577 def f(x):
578 def f(x):
578 called.add(x)
579 called.add(x)
579 ip.push({'f':f})
580 ip.push({'f':f})
580
581
581 with tt.AssertPrints("best of "):
582 with tt.AssertPrints("best of "):
582 ip.run_line_magic("timeit", "-n1 f(1)")
583 ip.run_line_magic("timeit", "-n1 f(1)")
583 self.assertEqual(called, set([(1,)]))
584 self.assertEqual(called, set([(1,)]))
584 called.clear()
585 called.clear()
585
586
586 with tt.AssertPrints("best of "):
587 with tt.AssertPrints("best of "):
587 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
588 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
588 self.assertEqual(called, set([(2,), (3,)]))
589 self.assertEqual(called, set([(2,), (3,)]))
589
590
590 class ErrorTransformer(ast.NodeTransformer):
591 class ErrorTransformer(ast.NodeTransformer):
591 """Throws an error when it sees a number."""
592 """Throws an error when it sees a number."""
592 def visit_Num(self):
593 def visit_Num(self):
593 raise ValueError("test")
594 raise ValueError("test")
594
595
595 class TestAstTransformError(unittest.TestCase):
596 class TestAstTransformError(unittest.TestCase):
596 def test_unregistering(self):
597 def test_unregistering(self):
597 err_transformer = ErrorTransformer()
598 err_transformer = ErrorTransformer()
598 ip.ast_transformers.append(err_transformer)
599 ip.ast_transformers.append(err_transformer)
599
600
600 with tt.AssertPrints("unregister", channel='stderr'):
601 with tt.AssertPrints("unregister", channel='stderr'):
601 ip.run_cell("1 + 2")
602 ip.run_cell("1 + 2")
602
603
603 # This should have been removed.
604 # This should have been removed.
604 nt.assert_not_in(err_transformer, ip.ast_transformers)
605 nt.assert_not_in(err_transformer, ip.ast_transformers)
605
606
606 def test__IPYTHON__():
607 def test__IPYTHON__():
607 # This shouldn't raise a NameError, that's all
608 # This shouldn't raise a NameError, that's all
608 __IPYTHON__
609 __IPYTHON__
609
610
610
611
611 class DummyRepr(object):
612 class DummyRepr(object):
612 def __repr__(self):
613 def __repr__(self):
613 return "DummyRepr"
614 return "DummyRepr"
614
615
615 def _repr_html_(self):
616 def _repr_html_(self):
616 return "<b>dummy</b>"
617 return "<b>dummy</b>"
617
618
618 def _repr_javascript_(self):
619 def _repr_javascript_(self):
619 return "console.log('hi');", {'key': 'value'}
620 return "console.log('hi');", {'key': 'value'}
620
621
621
622
622 def test_user_variables():
623 def test_user_variables():
623 # enable all formatters
624 # enable all formatters
624 ip.display_formatter.active_types = ip.display_formatter.format_types
625 ip.display_formatter.active_types = ip.display_formatter.format_types
625
626
626 ip.user_ns['dummy'] = d = DummyRepr()
627 ip.user_ns['dummy'] = d = DummyRepr()
627 keys = set(['dummy', 'doesnotexist'])
628 keys = set(['dummy', 'doesnotexist'])
628 r = ip.user_variables(keys)
629 r = ip.user_variables(keys)
629
630
630 nt.assert_equal(keys, set(r.keys()))
631 nt.assert_equal(keys, set(r.keys()))
631 dummy = r['dummy']
632 dummy = r['dummy']
632 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
633 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
633 nt.assert_equal(dummy['status'], 'ok')
634 nt.assert_equal(dummy['status'], 'ok')
634 data = dummy['data']
635 data = dummy['data']
635 metadata = dummy['metadata']
636 metadata = dummy['metadata']
636 nt.assert_equal(data.get('text/html'), d._repr_html_())
637 nt.assert_equal(data.get('text/html'), d._repr_html_())
637 js, jsmd = d._repr_javascript_()
638 js, jsmd = d._repr_javascript_()
638 nt.assert_equal(data.get('application/javascript'), js)
639 nt.assert_equal(data.get('application/javascript'), js)
639 nt.assert_equal(metadata.get('application/javascript'), jsmd)
640 nt.assert_equal(metadata.get('application/javascript'), jsmd)
640
641
641 dne = r['doesnotexist']
642 dne = r['doesnotexist']
642 nt.assert_equal(dne['status'], 'error')
643 nt.assert_equal(dne['status'], 'error')
643 nt.assert_equal(dne['ename'], 'KeyError')
644 nt.assert_equal(dne['ename'], 'KeyError')
644
645
645 # back to text only
646 # back to text only
646 ip.display_formatter.active_types = ['text/plain']
647 ip.display_formatter.active_types = ['text/plain']
647
648
648 def test_user_expression():
649 def test_user_expression():
649 # enable all formatters
650 # enable all formatters
650 ip.display_formatter.active_types = ip.display_formatter.format_types
651 ip.display_formatter.active_types = ip.display_formatter.format_types
651 query = {
652 query = {
652 'a' : '1 + 2',
653 'a' : '1 + 2',
653 'b' : '1/0',
654 'b' : '1/0',
654 }
655 }
655 r = ip.user_expressions(query)
656 r = ip.user_expressions(query)
656 import pprint
657 import pprint
657 pprint.pprint(r)
658 pprint.pprint(r)
658 nt.assert_equal(set(r.keys()), set(query.keys()))
659 nt.assert_equal(set(r.keys()), set(query.keys()))
659 a = r['a']
660 a = r['a']
660 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
661 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
661 nt.assert_equal(a['status'], 'ok')
662 nt.assert_equal(a['status'], 'ok')
662 data = a['data']
663 data = a['data']
663 metadata = a['metadata']
664 metadata = a['metadata']
664 nt.assert_equal(data.get('text/plain'), '3')
665 nt.assert_equal(data.get('text/plain'), '3')
665
666
666 b = r['b']
667 b = r['b']
667 nt.assert_equal(b['status'], 'error')
668 nt.assert_equal(b['status'], 'error')
668 nt.assert_equal(b['ename'], 'ZeroDivisionError')
669 nt.assert_equal(b['ename'], 'ZeroDivisionError')
669
670
670 # back to text only
671 # back to text only
671 ip.display_formatter.active_types = ['text/plain']
672 ip.display_formatter.active_types = ['text/plain']
672
673
673
674
674
675
675
676
676
677
678 class TestSyntaxErrorTransformer(unittest.TestCase):
679 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
680
681 class SyntaxErrorTransformer(InputTransformer):
682
683 def push(self, line):
684 pos = line.find('syntaxerror')
685 if pos >= 0:
686 e = SyntaxError('input contains "syntaxerror"')
687 e.text = line
688 e.offset = pos + 1
689 raise e
690 return line
691
692 def reset(self):
693 pass
694
695 def setUp(self):
696 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
697 ip.input_splitter.python_line_transforms.append(self.transformer)
698 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
699
700 def tearDown(self):
701 ip.input_splitter.python_line_transforms.remove(self.transformer)
702 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
703
704 def test_syntaxerror_input_transformer(self):
705 with tt.AssertPrints('1234'):
706 ip.run_cell('1234')
707 with tt.AssertPrints('SyntaxError: invalid syntax'):
708 ip.run_cell('1 2 3') # plain python syntax error
709 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
710 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
711 with tt.AssertPrints('3456'):
712 ip.run_cell('3456')
713
714
677
715
@@ -1,803 +1,806 b''
1 from __future__ import print_function
1 from __future__ import print_function
2
2
3 # Standard library imports
3 # Standard library imports
4 from collections import namedtuple
4 from collections import namedtuple
5 import sys
5 import sys
6 import uuid
6 import uuid
7
7
8 # System library imports
8 # System library imports
9 from IPython.external import qt
9 from IPython.external import qt
10 from IPython.external.qt import QtCore, QtGui
10 from IPython.external.qt import QtCore, QtGui
11 from IPython.utils import py3compat
11 from IPython.utils import py3compat
12 from IPython.utils.importstring import import_item
12 from IPython.utils.importstring import import_item
13
13
14 # Local imports
14 # Local imports
15 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
15 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
16 from IPython.core.inputtransformer import classic_prompt
16 from IPython.core.inputtransformer import classic_prompt
17 from IPython.core.oinspect import call_tip
17 from IPython.core.oinspect import call_tip
18 from IPython.qt.base_frontend_mixin import BaseFrontendMixin
18 from IPython.qt.base_frontend_mixin import BaseFrontendMixin
19 from IPython.utils.traitlets import Any, Bool, Instance, Unicode, DottedObjectName
19 from IPython.utils.traitlets import Any, Bool, Instance, Unicode, DottedObjectName
20 from .bracket_matcher import BracketMatcher
20 from .bracket_matcher import BracketMatcher
21 from .call_tip_widget import CallTipWidget
21 from .call_tip_widget import CallTipWidget
22 from .completion_lexer import CompletionLexer
22 from .completion_lexer import CompletionLexer
23 from .history_console_widget import HistoryConsoleWidget
23 from .history_console_widget import HistoryConsoleWidget
24 from .pygments_highlighter import PygmentsHighlighter
24 from .pygments_highlighter import PygmentsHighlighter
25
25
26
26
27 class FrontendHighlighter(PygmentsHighlighter):
27 class FrontendHighlighter(PygmentsHighlighter):
28 """ A PygmentsHighlighter that understands and ignores prompts.
28 """ A PygmentsHighlighter that understands and ignores prompts.
29 """
29 """
30
30
31 def __init__(self, frontend, lexer=None):
31 def __init__(self, frontend, lexer=None):
32 super(FrontendHighlighter, self).__init__(frontend._control.document(), lexer=lexer)
32 super(FrontendHighlighter, self).__init__(frontend._control.document(), lexer=lexer)
33 self._current_offset = 0
33 self._current_offset = 0
34 self._frontend = frontend
34 self._frontend = frontend
35 self.highlighting_on = False
35 self.highlighting_on = False
36
36
37 def highlightBlock(self, string):
37 def highlightBlock(self, string):
38 """ Highlight a block of text. Reimplemented to highlight selectively.
38 """ Highlight a block of text. Reimplemented to highlight selectively.
39 """
39 """
40 if not self.highlighting_on:
40 if not self.highlighting_on:
41 return
41 return
42
42
43 # The input to this function is a unicode string that may contain
43 # The input to this function is a unicode string that may contain
44 # paragraph break characters, non-breaking spaces, etc. Here we acquire
44 # paragraph break characters, non-breaking spaces, etc. Here we acquire
45 # the string as plain text so we can compare it.
45 # the string as plain text so we can compare it.
46 current_block = self.currentBlock()
46 current_block = self.currentBlock()
47 string = self._frontend._get_block_plain_text(current_block)
47 string = self._frontend._get_block_plain_text(current_block)
48
48
49 # Decide whether to check for the regular or continuation prompt.
49 # Decide whether to check for the regular or continuation prompt.
50 if current_block.contains(self._frontend._prompt_pos):
50 if current_block.contains(self._frontend._prompt_pos):
51 prompt = self._frontend._prompt
51 prompt = self._frontend._prompt
52 else:
52 else:
53 prompt = self._frontend._continuation_prompt
53 prompt = self._frontend._continuation_prompt
54
54
55 # Only highlight if we can identify a prompt, but make sure not to
55 # Only highlight if we can identify a prompt, but make sure not to
56 # highlight the prompt.
56 # highlight the prompt.
57 if string.startswith(prompt):
57 if string.startswith(prompt):
58 self._current_offset = len(prompt)
58 self._current_offset = len(prompt)
59 string = string[len(prompt):]
59 string = string[len(prompt):]
60 super(FrontendHighlighter, self).highlightBlock(string)
60 super(FrontendHighlighter, self).highlightBlock(string)
61
61
62 def rehighlightBlock(self, block):
62 def rehighlightBlock(self, block):
63 """ Reimplemented to temporarily enable highlighting if disabled.
63 """ Reimplemented to temporarily enable highlighting if disabled.
64 """
64 """
65 old = self.highlighting_on
65 old = self.highlighting_on
66 self.highlighting_on = True
66 self.highlighting_on = True
67 super(FrontendHighlighter, self).rehighlightBlock(block)
67 super(FrontendHighlighter, self).rehighlightBlock(block)
68 self.highlighting_on = old
68 self.highlighting_on = old
69
69
70 def setFormat(self, start, count, format):
70 def setFormat(self, start, count, format):
71 """ Reimplemented to highlight selectively.
71 """ Reimplemented to highlight selectively.
72 """
72 """
73 start += self._current_offset
73 start += self._current_offset
74 super(FrontendHighlighter, self).setFormat(start, count, format)
74 super(FrontendHighlighter, self).setFormat(start, count, format)
75
75
76
76
77 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
77 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
78 """ A Qt frontend for a generic Python kernel.
78 """ A Qt frontend for a generic Python kernel.
79 """
79 """
80
80
81 # The text to show when the kernel is (re)started.
81 # The text to show when the kernel is (re)started.
82 banner = Unicode(config=True)
82 banner = Unicode(config=True)
83
83
84 # An option and corresponding signal for overriding the default kernel
84 # An option and corresponding signal for overriding the default kernel
85 # interrupt behavior.
85 # interrupt behavior.
86 custom_interrupt = Bool(False)
86 custom_interrupt = Bool(False)
87 custom_interrupt_requested = QtCore.Signal()
87 custom_interrupt_requested = QtCore.Signal()
88
88
89 # An option and corresponding signals for overriding the default kernel
89 # An option and corresponding signals for overriding the default kernel
90 # restart behavior.
90 # restart behavior.
91 custom_restart = Bool(False)
91 custom_restart = Bool(False)
92 custom_restart_kernel_died = QtCore.Signal(float)
92 custom_restart_kernel_died = QtCore.Signal(float)
93 custom_restart_requested = QtCore.Signal()
93 custom_restart_requested = QtCore.Signal()
94
94
95 # Whether to automatically show calltips on open-parentheses.
95 # Whether to automatically show calltips on open-parentheses.
96 enable_calltips = Bool(True, config=True,
96 enable_calltips = Bool(True, config=True,
97 help="Whether to draw information calltips on open-parentheses.")
97 help="Whether to draw information calltips on open-parentheses.")
98
98
99 clear_on_kernel_restart = Bool(True, config=True,
99 clear_on_kernel_restart = Bool(True, config=True,
100 help="Whether to clear the console when the kernel is restarted")
100 help="Whether to clear the console when the kernel is restarted")
101
101
102 confirm_restart = Bool(True, config=True,
102 confirm_restart = Bool(True, config=True,
103 help="Whether to ask for user confirmation when restarting kernel")
103 help="Whether to ask for user confirmation when restarting kernel")
104
104
105 lexer_class = DottedObjectName(config=True,
105 lexer_class = DottedObjectName(config=True,
106 help="The pygments lexer class to use."
106 help="The pygments lexer class to use."
107 )
107 )
108 def _lexer_class_changed(self, name, old, new):
108 def _lexer_class_changed(self, name, old, new):
109 lexer_class = import_item(new)
109 lexer_class = import_item(new)
110 self.lexer = lexer_class()
110 self.lexer = lexer_class()
111
111
112 def _lexer_class_default(self):
112 def _lexer_class_default(self):
113 if py3compat.PY3:
113 if py3compat.PY3:
114 return 'pygments.lexers.Python3Lexer'
114 return 'pygments.lexers.Python3Lexer'
115 else:
115 else:
116 return 'pygments.lexers.PythonLexer'
116 return 'pygments.lexers.PythonLexer'
117
117
118 lexer = Any()
118 lexer = Any()
119 def _lexer_default(self):
119 def _lexer_default(self):
120 lexer_class = import_item(self.lexer_class)
120 lexer_class = import_item(self.lexer_class)
121 return lexer_class()
121 return lexer_class()
122
122
123 # Emitted when a user visible 'execute_request' has been submitted to the
123 # Emitted when a user visible 'execute_request' has been submitted to the
124 # kernel from the FrontendWidget. Contains the code to be executed.
124 # kernel from the FrontendWidget. Contains the code to be executed.
125 executing = QtCore.Signal(object)
125 executing = QtCore.Signal(object)
126
126
127 # Emitted when a user-visible 'execute_reply' has been received from the
127 # Emitted when a user-visible 'execute_reply' has been received from the
128 # kernel and processed by the FrontendWidget. Contains the response message.
128 # kernel and processed by the FrontendWidget. Contains the response message.
129 executed = QtCore.Signal(object)
129 executed = QtCore.Signal(object)
130
130
131 # Emitted when an exit request has been received from the kernel.
131 # Emitted when an exit request has been received from the kernel.
132 exit_requested = QtCore.Signal(object)
132 exit_requested = QtCore.Signal(object)
133
133
134 # Protected class variables.
134 # Protected class variables.
135 _prompt_transformer = IPythonInputSplitter(physical_line_transforms=[classic_prompt()],
135 _prompt_transformer = IPythonInputSplitter(physical_line_transforms=[classic_prompt()],
136 logical_line_transforms=[],
136 logical_line_transforms=[],
137 python_line_transforms=[],
137 python_line_transforms=[],
138 )
138 )
139 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
139 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
140 _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
140 _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
141 _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind'])
141 _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind'])
142 _input_splitter_class = InputSplitter
142 _input_splitter_class = InputSplitter
143 _local_kernel = False
143 _local_kernel = False
144 _highlighter = Instance(FrontendHighlighter)
144 _highlighter = Instance(FrontendHighlighter)
145
145
146 #---------------------------------------------------------------------------
146 #---------------------------------------------------------------------------
147 # 'object' interface
147 # 'object' interface
148 #---------------------------------------------------------------------------
148 #---------------------------------------------------------------------------
149
149
150 def __init__(self, *args, **kw):
150 def __init__(self, *args, **kw):
151 super(FrontendWidget, self).__init__(*args, **kw)
151 super(FrontendWidget, self).__init__(*args, **kw)
152 # FIXME: remove this when PySide min version is updated past 1.0.7
152 # FIXME: remove this when PySide min version is updated past 1.0.7
153 # forcefully disable calltips if PySide is < 1.0.7, because they crash
153 # forcefully disable calltips if PySide is < 1.0.7, because they crash
154 if qt.QT_API == qt.QT_API_PYSIDE:
154 if qt.QT_API == qt.QT_API_PYSIDE:
155 import PySide
155 import PySide
156 if PySide.__version_info__ < (1,0,7):
156 if PySide.__version_info__ < (1,0,7):
157 self.log.warn("PySide %s < 1.0.7 detected, disabling calltips" % PySide.__version__)
157 self.log.warn("PySide %s < 1.0.7 detected, disabling calltips" % PySide.__version__)
158 self.enable_calltips = False
158 self.enable_calltips = False
159
159
160 # FrontendWidget protected variables.
160 # FrontendWidget protected variables.
161 self._bracket_matcher = BracketMatcher(self._control)
161 self._bracket_matcher = BracketMatcher(self._control)
162 self._call_tip_widget = CallTipWidget(self._control)
162 self._call_tip_widget = CallTipWidget(self._control)
163 self._completion_lexer = CompletionLexer(self.lexer)
163 self._completion_lexer = CompletionLexer(self.lexer)
164 self._copy_raw_action = QtGui.QAction('Copy (Raw Text)', None)
164 self._copy_raw_action = QtGui.QAction('Copy (Raw Text)', None)
165 self._hidden = False
165 self._hidden = False
166 self._highlighter = FrontendHighlighter(self, lexer=self.lexer)
166 self._highlighter = FrontendHighlighter(self, lexer=self.lexer)
167 self._input_splitter = self._input_splitter_class()
167 self._input_splitter = self._input_splitter_class()
168 self._kernel_manager = None
168 self._kernel_manager = None
169 self._kernel_client = None
169 self._kernel_client = None
170 self._request_info = {}
170 self._request_info = {}
171 self._request_info['execute'] = {};
171 self._request_info['execute'] = {};
172 self._callback_dict = {}
172 self._callback_dict = {}
173
173
174 # Configure the ConsoleWidget.
174 # Configure the ConsoleWidget.
175 self.tab_width = 4
175 self.tab_width = 4
176 self._set_continuation_prompt('... ')
176 self._set_continuation_prompt('... ')
177
177
178 # Configure the CallTipWidget.
178 # Configure the CallTipWidget.
179 self._call_tip_widget.setFont(self.font)
179 self._call_tip_widget.setFont(self.font)
180 self.font_changed.connect(self._call_tip_widget.setFont)
180 self.font_changed.connect(self._call_tip_widget.setFont)
181
181
182 # Configure actions.
182 # Configure actions.
183 action = self._copy_raw_action
183 action = self._copy_raw_action
184 key = QtCore.Qt.CTRL | QtCore.Qt.SHIFT | QtCore.Qt.Key_C
184 key = QtCore.Qt.CTRL | QtCore.Qt.SHIFT | QtCore.Qt.Key_C
185 action.setEnabled(False)
185 action.setEnabled(False)
186 action.setShortcut(QtGui.QKeySequence(key))
186 action.setShortcut(QtGui.QKeySequence(key))
187 action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
187 action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
188 action.triggered.connect(self.copy_raw)
188 action.triggered.connect(self.copy_raw)
189 self.copy_available.connect(action.setEnabled)
189 self.copy_available.connect(action.setEnabled)
190 self.addAction(action)
190 self.addAction(action)
191
191
192 # Connect signal handlers.
192 # Connect signal handlers.
193 document = self._control.document()
193 document = self._control.document()
194 document.contentsChange.connect(self._document_contents_change)
194 document.contentsChange.connect(self._document_contents_change)
195
195
196 # Set flag for whether we are connected via localhost.
196 # Set flag for whether we are connected via localhost.
197 self._local_kernel = kw.get('local_kernel',
197 self._local_kernel = kw.get('local_kernel',
198 FrontendWidget._local_kernel)
198 FrontendWidget._local_kernel)
199
199
200 #---------------------------------------------------------------------------
200 #---------------------------------------------------------------------------
201 # 'ConsoleWidget' public interface
201 # 'ConsoleWidget' public interface
202 #---------------------------------------------------------------------------
202 #---------------------------------------------------------------------------
203
203
204 def copy(self):
204 def copy(self):
205 """ Copy the currently selected text to the clipboard, removing prompts.
205 """ Copy the currently selected text to the clipboard, removing prompts.
206 """
206 """
207 if self._page_control is not None and self._page_control.hasFocus():
207 if self._page_control is not None and self._page_control.hasFocus():
208 self._page_control.copy()
208 self._page_control.copy()
209 elif self._control.hasFocus():
209 elif self._control.hasFocus():
210 text = self._control.textCursor().selection().toPlainText()
210 text = self._control.textCursor().selection().toPlainText()
211 if text:
211 if text:
212 text = self._prompt_transformer.transform_cell(text)
212 text = self._prompt_transformer.transform_cell(text)
213 QtGui.QApplication.clipboard().setText(text)
213 QtGui.QApplication.clipboard().setText(text)
214 else:
214 else:
215 self.log.debug("frontend widget : unknown copy target")
215 self.log.debug("frontend widget : unknown copy target")
216
216
217 #---------------------------------------------------------------------------
217 #---------------------------------------------------------------------------
218 # 'ConsoleWidget' abstract interface
218 # 'ConsoleWidget' abstract interface
219 #---------------------------------------------------------------------------
219 #---------------------------------------------------------------------------
220
220
221 def _is_complete(self, source, interactive):
221 def _is_complete(self, source, interactive):
222 """ Returns whether 'source' can be completely processed and a new
222 """ Returns whether 'source' can be completely processed and a new
223 prompt created. When triggered by an Enter/Return key press,
223 prompt created. When triggered by an Enter/Return key press,
224 'interactive' is True; otherwise, it is False.
224 'interactive' is True; otherwise, it is False.
225 """
225 """
226 self._input_splitter.reset()
226 self._input_splitter.reset()
227 complete = self._input_splitter.push(source)
227 try:
228 complete = self._input_splitter.push(source)
229 except SyntaxError:
230 return True
228 if interactive:
231 if interactive:
229 complete = not self._input_splitter.push_accepts_more()
232 complete = not self._input_splitter.push_accepts_more()
230 return complete
233 return complete
231
234
232 def _execute(self, source, hidden):
235 def _execute(self, source, hidden):
233 """ Execute 'source'. If 'hidden', do not show any output.
236 """ Execute 'source'. If 'hidden', do not show any output.
234
237
235 See parent class :meth:`execute` docstring for full details.
238 See parent class :meth:`execute` docstring for full details.
236 """
239 """
237 msg_id = self.kernel_client.execute(source, hidden)
240 msg_id = self.kernel_client.execute(source, hidden)
238 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user')
241 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user')
239 self._hidden = hidden
242 self._hidden = hidden
240 if not hidden:
243 if not hidden:
241 self.executing.emit(source)
244 self.executing.emit(source)
242
245
243 def _prompt_started_hook(self):
246 def _prompt_started_hook(self):
244 """ Called immediately after a new prompt is displayed.
247 """ Called immediately after a new prompt is displayed.
245 """
248 """
246 if not self._reading:
249 if not self._reading:
247 self._highlighter.highlighting_on = True
250 self._highlighter.highlighting_on = True
248
251
249 def _prompt_finished_hook(self):
252 def _prompt_finished_hook(self):
250 """ Called immediately after a prompt is finished, i.e. when some input
253 """ Called immediately after a prompt is finished, i.e. when some input
251 will be processed and a new prompt displayed.
254 will be processed and a new prompt displayed.
252 """
255 """
253 # Flush all state from the input splitter so the next round of
256 # Flush all state from the input splitter so the next round of
254 # reading input starts with a clean buffer.
257 # reading input starts with a clean buffer.
255 self._input_splitter.reset()
258 self._input_splitter.reset()
256
259
257 if not self._reading:
260 if not self._reading:
258 self._highlighter.highlighting_on = False
261 self._highlighter.highlighting_on = False
259
262
260 def _tab_pressed(self):
263 def _tab_pressed(self):
261 """ Called when the tab key is pressed. Returns whether to continue
264 """ Called when the tab key is pressed. Returns whether to continue
262 processing the event.
265 processing the event.
263 """
266 """
264 # Perform tab completion if:
267 # Perform tab completion if:
265 # 1) The cursor is in the input buffer.
268 # 1) The cursor is in the input buffer.
266 # 2) There is a non-whitespace character before the cursor.
269 # 2) There is a non-whitespace character before the cursor.
267 text = self._get_input_buffer_cursor_line()
270 text = self._get_input_buffer_cursor_line()
268 if text is None:
271 if text is None:
269 return False
272 return False
270 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
273 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
271 if complete:
274 if complete:
272 self._complete()
275 self._complete()
273 return not complete
276 return not complete
274
277
275 #---------------------------------------------------------------------------
278 #---------------------------------------------------------------------------
276 # 'ConsoleWidget' protected interface
279 # 'ConsoleWidget' protected interface
277 #---------------------------------------------------------------------------
280 #---------------------------------------------------------------------------
278
281
279 def _context_menu_make(self, pos):
282 def _context_menu_make(self, pos):
280 """ Reimplemented to add an action for raw copy.
283 """ Reimplemented to add an action for raw copy.
281 """
284 """
282 menu = super(FrontendWidget, self)._context_menu_make(pos)
285 menu = super(FrontendWidget, self)._context_menu_make(pos)
283 for before_action in menu.actions():
286 for before_action in menu.actions():
284 if before_action.shortcut().matches(QtGui.QKeySequence.Paste) == \
287 if before_action.shortcut().matches(QtGui.QKeySequence.Paste) == \
285 QtGui.QKeySequence.ExactMatch:
288 QtGui.QKeySequence.ExactMatch:
286 menu.insertAction(before_action, self._copy_raw_action)
289 menu.insertAction(before_action, self._copy_raw_action)
287 break
290 break
288 return menu
291 return menu
289
292
290 def request_interrupt_kernel(self):
293 def request_interrupt_kernel(self):
291 if self._executing:
294 if self._executing:
292 self.interrupt_kernel()
295 self.interrupt_kernel()
293
296
294 def request_restart_kernel(self):
297 def request_restart_kernel(self):
295 message = 'Are you sure you want to restart the kernel?'
298 message = 'Are you sure you want to restart the kernel?'
296 self.restart_kernel(message, now=False)
299 self.restart_kernel(message, now=False)
297
300
298 def _event_filter_console_keypress(self, event):
301 def _event_filter_console_keypress(self, event):
299 """ Reimplemented for execution interruption and smart backspace.
302 """ Reimplemented for execution interruption and smart backspace.
300 """
303 """
301 key = event.key()
304 key = event.key()
302 if self._control_key_down(event.modifiers(), include_command=False):
305 if self._control_key_down(event.modifiers(), include_command=False):
303
306
304 if key == QtCore.Qt.Key_C and self._executing:
307 if key == QtCore.Qt.Key_C and self._executing:
305 self.request_interrupt_kernel()
308 self.request_interrupt_kernel()
306 return True
309 return True
307
310
308 elif key == QtCore.Qt.Key_Period:
311 elif key == QtCore.Qt.Key_Period:
309 self.request_restart_kernel()
312 self.request_restart_kernel()
310 return True
313 return True
311
314
312 elif not event.modifiers() & QtCore.Qt.AltModifier:
315 elif not event.modifiers() & QtCore.Qt.AltModifier:
313
316
314 # Smart backspace: remove four characters in one backspace if:
317 # Smart backspace: remove four characters in one backspace if:
315 # 1) everything left of the cursor is whitespace
318 # 1) everything left of the cursor is whitespace
316 # 2) the four characters immediately left of the cursor are spaces
319 # 2) the four characters immediately left of the cursor are spaces
317 if key == QtCore.Qt.Key_Backspace:
320 if key == QtCore.Qt.Key_Backspace:
318 col = self._get_input_buffer_cursor_column()
321 col = self._get_input_buffer_cursor_column()
319 cursor = self._control.textCursor()
322 cursor = self._control.textCursor()
320 if col > 3 and not cursor.hasSelection():
323 if col > 3 and not cursor.hasSelection():
321 text = self._get_input_buffer_cursor_line()[:col]
324 text = self._get_input_buffer_cursor_line()[:col]
322 if text.endswith(' ') and not text.strip():
325 if text.endswith(' ') and not text.strip():
323 cursor.movePosition(QtGui.QTextCursor.Left,
326 cursor.movePosition(QtGui.QTextCursor.Left,
324 QtGui.QTextCursor.KeepAnchor, 4)
327 QtGui.QTextCursor.KeepAnchor, 4)
325 cursor.removeSelectedText()
328 cursor.removeSelectedText()
326 return True
329 return True
327
330
328 return super(FrontendWidget, self)._event_filter_console_keypress(event)
331 return super(FrontendWidget, self)._event_filter_console_keypress(event)
329
332
330 def _insert_continuation_prompt(self, cursor):
333 def _insert_continuation_prompt(self, cursor):
331 """ Reimplemented for auto-indentation.
334 """ Reimplemented for auto-indentation.
332 """
335 """
333 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
336 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
334 cursor.insertText(' ' * self._input_splitter.indent_spaces)
337 cursor.insertText(' ' * self._input_splitter.indent_spaces)
335
338
336 #---------------------------------------------------------------------------
339 #---------------------------------------------------------------------------
337 # 'BaseFrontendMixin' abstract interface
340 # 'BaseFrontendMixin' abstract interface
338 #---------------------------------------------------------------------------
341 #---------------------------------------------------------------------------
339
342
340 def _handle_complete_reply(self, rep):
343 def _handle_complete_reply(self, rep):
341 """ Handle replies for tab completion.
344 """ Handle replies for tab completion.
342 """
345 """
343 self.log.debug("complete: %s", rep.get('content', ''))
346 self.log.debug("complete: %s", rep.get('content', ''))
344 cursor = self._get_cursor()
347 cursor = self._get_cursor()
345 info = self._request_info.get('complete')
348 info = self._request_info.get('complete')
346 if info and info.id == rep['parent_header']['msg_id'] and \
349 if info and info.id == rep['parent_header']['msg_id'] and \
347 info.pos == cursor.position():
350 info.pos == cursor.position():
348 text = '.'.join(self._get_context())
351 text = '.'.join(self._get_context())
349 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
352 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
350 self._complete_with_items(cursor, rep['content']['matches'])
353 self._complete_with_items(cursor, rep['content']['matches'])
351
354
352 def _silent_exec_callback(self, expr, callback):
355 def _silent_exec_callback(self, expr, callback):
353 """Silently execute `expr` in the kernel and call `callback` with reply
356 """Silently execute `expr` in the kernel and call `callback` with reply
354
357
355 the `expr` is evaluated silently in the kernel (without) output in
358 the `expr` is evaluated silently in the kernel (without) output in
356 the frontend. Call `callback` with the
359 the frontend. Call `callback` with the
357 `repr <http://docs.python.org/library/functions.html#repr> `_ as first argument
360 `repr <http://docs.python.org/library/functions.html#repr> `_ as first argument
358
361
359 Parameters
362 Parameters
360 ----------
363 ----------
361 expr : string
364 expr : string
362 valid string to be executed by the kernel.
365 valid string to be executed by the kernel.
363 callback : function
366 callback : function
364 function accepting one argument, as a string. The string will be
367 function accepting one argument, as a string. The string will be
365 the `repr` of the result of evaluating `expr`
368 the `repr` of the result of evaluating `expr`
366
369
367 The `callback` is called with the `repr()` of the result of `expr` as
370 The `callback` is called with the `repr()` of the result of `expr` as
368 first argument. To get the object, do `eval()` on the passed value.
371 first argument. To get the object, do `eval()` on the passed value.
369
372
370 See Also
373 See Also
371 --------
374 --------
372 _handle_exec_callback : private method, deal with calling callback with reply
375 _handle_exec_callback : private method, deal with calling callback with reply
373
376
374 """
377 """
375
378
376 # generate uuid, which would be used as an indication of whether or
379 # generate uuid, which would be used as an indication of whether or
377 # not the unique request originated from here (can use msg id ?)
380 # not the unique request originated from here (can use msg id ?)
378 local_uuid = str(uuid.uuid1())
381 local_uuid = str(uuid.uuid1())
379 msg_id = self.kernel_client.execute('',
382 msg_id = self.kernel_client.execute('',
380 silent=True, user_expressions={ local_uuid:expr })
383 silent=True, user_expressions={ local_uuid:expr })
381 self._callback_dict[local_uuid] = callback
384 self._callback_dict[local_uuid] = callback
382 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'silent_exec_callback')
385 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'silent_exec_callback')
383
386
384 def _handle_exec_callback(self, msg):
387 def _handle_exec_callback(self, msg):
385 """Execute `callback` corresponding to `msg` reply, after ``_silent_exec_callback``
388 """Execute `callback` corresponding to `msg` reply, after ``_silent_exec_callback``
386
389
387 Parameters
390 Parameters
388 ----------
391 ----------
389 msg : raw message send by the kernel containing an `user_expressions`
392 msg : raw message send by the kernel containing an `user_expressions`
390 and having a 'silent_exec_callback' kind.
393 and having a 'silent_exec_callback' kind.
391
394
392 Notes
395 Notes
393 -----
396 -----
394 This function will look for a `callback` associated with the
397 This function will look for a `callback` associated with the
395 corresponding message id. Association has been made by
398 corresponding message id. Association has been made by
396 `_silent_exec_callback`. `callback` is then called with the `repr()`
399 `_silent_exec_callback`. `callback` is then called with the `repr()`
397 of the value of corresponding `user_expressions` as argument.
400 of the value of corresponding `user_expressions` as argument.
398 `callback` is then removed from the known list so that any message
401 `callback` is then removed from the known list so that any message
399 coming again with the same id won't trigger it.
402 coming again with the same id won't trigger it.
400
403
401 """
404 """
402
405
403 user_exp = msg['content'].get('user_expressions')
406 user_exp = msg['content'].get('user_expressions')
404 if not user_exp:
407 if not user_exp:
405 return
408 return
406 for expression in user_exp:
409 for expression in user_exp:
407 if expression in self._callback_dict:
410 if expression in self._callback_dict:
408 self._callback_dict.pop(expression)(user_exp[expression])
411 self._callback_dict.pop(expression)(user_exp[expression])
409
412
410 def _handle_execute_reply(self, msg):
413 def _handle_execute_reply(self, msg):
411 """ Handles replies for code execution.
414 """ Handles replies for code execution.
412 """
415 """
413 self.log.debug("execute: %s", msg.get('content', ''))
416 self.log.debug("execute: %s", msg.get('content', ''))
414 msg_id = msg['parent_header']['msg_id']
417 msg_id = msg['parent_header']['msg_id']
415 info = self._request_info['execute'].get(msg_id)
418 info = self._request_info['execute'].get(msg_id)
416 # unset reading flag, because if execute finished, raw_input can't
419 # unset reading flag, because if execute finished, raw_input can't
417 # still be pending.
420 # still be pending.
418 self._reading = False
421 self._reading = False
419 if info and info.kind == 'user' and not self._hidden:
422 if info and info.kind == 'user' and not self._hidden:
420 # Make sure that all output from the SUB channel has been processed
423 # Make sure that all output from the SUB channel has been processed
421 # before writing a new prompt.
424 # before writing a new prompt.
422 self.kernel_client.iopub_channel.flush()
425 self.kernel_client.iopub_channel.flush()
423
426
424 # Reset the ANSI style information to prevent bad text in stdout
427 # Reset the ANSI style information to prevent bad text in stdout
425 # from messing up our colors. We're not a true terminal so we're
428 # from messing up our colors. We're not a true terminal so we're
426 # allowed to do this.
429 # allowed to do this.
427 if self.ansi_codes:
430 if self.ansi_codes:
428 self._ansi_processor.reset_sgr()
431 self._ansi_processor.reset_sgr()
429
432
430 content = msg['content']
433 content = msg['content']
431 status = content['status']
434 status = content['status']
432 if status == 'ok':
435 if status == 'ok':
433 self._process_execute_ok(msg)
436 self._process_execute_ok(msg)
434 elif status == 'error':
437 elif status == 'error':
435 self._process_execute_error(msg)
438 self._process_execute_error(msg)
436 elif status == 'aborted':
439 elif status == 'aborted':
437 self._process_execute_abort(msg)
440 self._process_execute_abort(msg)
438
441
439 self._show_interpreter_prompt_for_reply(msg)
442 self._show_interpreter_prompt_for_reply(msg)
440 self.executed.emit(msg)
443 self.executed.emit(msg)
441 self._request_info['execute'].pop(msg_id)
444 self._request_info['execute'].pop(msg_id)
442 elif info and info.kind == 'silent_exec_callback' and not self._hidden:
445 elif info and info.kind == 'silent_exec_callback' and not self._hidden:
443 self._handle_exec_callback(msg)
446 self._handle_exec_callback(msg)
444 self._request_info['execute'].pop(msg_id)
447 self._request_info['execute'].pop(msg_id)
445 else:
448 else:
446 super(FrontendWidget, self)._handle_execute_reply(msg)
449 super(FrontendWidget, self)._handle_execute_reply(msg)
447
450
448 def _handle_input_request(self, msg):
451 def _handle_input_request(self, msg):
449 """ Handle requests for raw_input.
452 """ Handle requests for raw_input.
450 """
453 """
451 self.log.debug("input: %s", msg.get('content', ''))
454 self.log.debug("input: %s", msg.get('content', ''))
452 if self._hidden:
455 if self._hidden:
453 raise RuntimeError('Request for raw input during hidden execution.')
456 raise RuntimeError('Request for raw input during hidden execution.')
454
457
455 # Make sure that all output from the SUB channel has been processed
458 # Make sure that all output from the SUB channel has been processed
456 # before entering readline mode.
459 # before entering readline mode.
457 self.kernel_client.iopub_channel.flush()
460 self.kernel_client.iopub_channel.flush()
458
461
459 def callback(line):
462 def callback(line):
460 self.kernel_client.stdin_channel.input(line)
463 self.kernel_client.stdin_channel.input(line)
461 if self._reading:
464 if self._reading:
462 self.log.debug("Got second input request, assuming first was interrupted.")
465 self.log.debug("Got second input request, assuming first was interrupted.")
463 self._reading = False
466 self._reading = False
464 self._readline(msg['content']['prompt'], callback=callback)
467 self._readline(msg['content']['prompt'], callback=callback)
465
468
466 def _kernel_restarted_message(self, died=True):
469 def _kernel_restarted_message(self, died=True):
467 msg = "Kernel died, restarting" if died else "Kernel restarting"
470 msg = "Kernel died, restarting" if died else "Kernel restarting"
468 self._append_html("<br>%s<hr><br>" % msg,
471 self._append_html("<br>%s<hr><br>" % msg,
469 before_prompt=False
472 before_prompt=False
470 )
473 )
471
474
472 def _handle_kernel_died(self, since_last_heartbeat):
475 def _handle_kernel_died(self, since_last_heartbeat):
473 """Handle the kernel's death (if we do not own the kernel).
476 """Handle the kernel's death (if we do not own the kernel).
474 """
477 """
475 self.log.warn("kernel died: %s", since_last_heartbeat)
478 self.log.warn("kernel died: %s", since_last_heartbeat)
476 if self.custom_restart:
479 if self.custom_restart:
477 self.custom_restart_kernel_died.emit(since_last_heartbeat)
480 self.custom_restart_kernel_died.emit(since_last_heartbeat)
478 else:
481 else:
479 self._kernel_restarted_message(died=True)
482 self._kernel_restarted_message(died=True)
480 self.reset()
483 self.reset()
481
484
482 def _handle_kernel_restarted(self, died=True):
485 def _handle_kernel_restarted(self, died=True):
483 """Notice that the autorestarter restarted the kernel.
486 """Notice that the autorestarter restarted the kernel.
484
487
485 There's nothing to do but show a message.
488 There's nothing to do but show a message.
486 """
489 """
487 self.log.warn("kernel restarted")
490 self.log.warn("kernel restarted")
488 self._kernel_restarted_message(died=died)
491 self._kernel_restarted_message(died=died)
489 self.reset()
492 self.reset()
490
493
491 def _handle_object_info_reply(self, rep):
494 def _handle_object_info_reply(self, rep):
492 """ Handle replies for call tips.
495 """ Handle replies for call tips.
493 """
496 """
494 self.log.debug("oinfo: %s", rep.get('content', ''))
497 self.log.debug("oinfo: %s", rep.get('content', ''))
495 cursor = self._get_cursor()
498 cursor = self._get_cursor()
496 info = self._request_info.get('call_tip')
499 info = self._request_info.get('call_tip')
497 if info and info.id == rep['parent_header']['msg_id'] and \
500 if info and info.id == rep['parent_header']['msg_id'] and \
498 info.pos == cursor.position():
501 info.pos == cursor.position():
499 # Get the information for a call tip. For now we format the call
502 # Get the information for a call tip. For now we format the call
500 # line as string, later we can pass False to format_call and
503 # line as string, later we can pass False to format_call and
501 # syntax-highlight it ourselves for nicer formatting in the
504 # syntax-highlight it ourselves for nicer formatting in the
502 # calltip.
505 # calltip.
503 content = rep['content']
506 content = rep['content']
504 # if this is from pykernel, 'docstring' will be the only key
507 # if this is from pykernel, 'docstring' will be the only key
505 if content.get('ismagic', False):
508 if content.get('ismagic', False):
506 # Don't generate a call-tip for magics. Ideally, we should
509 # Don't generate a call-tip for magics. Ideally, we should
507 # generate a tooltip, but not on ( like we do for actual
510 # generate a tooltip, but not on ( like we do for actual
508 # callables.
511 # callables.
509 call_info, doc = None, None
512 call_info, doc = None, None
510 else:
513 else:
511 call_info, doc = call_tip(content, format_call=True)
514 call_info, doc = call_tip(content, format_call=True)
512 if call_info or doc:
515 if call_info or doc:
513 self._call_tip_widget.show_call_info(call_info, doc)
516 self._call_tip_widget.show_call_info(call_info, doc)
514
517
515 def _handle_pyout(self, msg):
518 def _handle_pyout(self, msg):
516 """ Handle display hook output.
519 """ Handle display hook output.
517 """
520 """
518 self.log.debug("pyout: %s", msg.get('content', ''))
521 self.log.debug("pyout: %s", msg.get('content', ''))
519 if not self._hidden and self._is_from_this_session(msg):
522 if not self._hidden and self._is_from_this_session(msg):
520 text = msg['content']['data']
523 text = msg['content']['data']
521 self._append_plain_text(text + '\n', before_prompt=True)
524 self._append_plain_text(text + '\n', before_prompt=True)
522
525
523 def _handle_stream(self, msg):
526 def _handle_stream(self, msg):
524 """ Handle stdout, stderr, and stdin.
527 """ Handle stdout, stderr, and stdin.
525 """
528 """
526 self.log.debug("stream: %s", msg.get('content', ''))
529 self.log.debug("stream: %s", msg.get('content', ''))
527 if not self._hidden and self._is_from_this_session(msg):
530 if not self._hidden and self._is_from_this_session(msg):
528 # Most consoles treat tabs as being 8 space characters. Convert tabs
531 # Most consoles treat tabs as being 8 space characters. Convert tabs
529 # to spaces so that output looks as expected regardless of this
532 # to spaces so that output looks as expected regardless of this
530 # widget's tab width.
533 # widget's tab width.
531 text = msg['content']['data'].expandtabs(8)
534 text = msg['content']['data'].expandtabs(8)
532
535
533 self._append_plain_text(text, before_prompt=True)
536 self._append_plain_text(text, before_prompt=True)
534 self._control.moveCursor(QtGui.QTextCursor.End)
537 self._control.moveCursor(QtGui.QTextCursor.End)
535
538
536 def _handle_shutdown_reply(self, msg):
539 def _handle_shutdown_reply(self, msg):
537 """ Handle shutdown signal, only if from other console.
540 """ Handle shutdown signal, only if from other console.
538 """
541 """
539 self.log.warn("shutdown: %s", msg.get('content', ''))
542 self.log.warn("shutdown: %s", msg.get('content', ''))
540 restart = msg.get('content', {}).get('restart', False)
543 restart = msg.get('content', {}).get('restart', False)
541 if not self._hidden and not self._is_from_this_session(msg):
544 if not self._hidden and not self._is_from_this_session(msg):
542 # got shutdown reply, request came from session other than ours
545 # got shutdown reply, request came from session other than ours
543 if restart:
546 if restart:
544 # someone restarted the kernel, handle it
547 # someone restarted the kernel, handle it
545 self._handle_kernel_restarted(died=False)
548 self._handle_kernel_restarted(died=False)
546 else:
549 else:
547 # kernel was shutdown permanently
550 # kernel was shutdown permanently
548 # this triggers exit_requested if the kernel was local,
551 # this triggers exit_requested if the kernel was local,
549 # and a dialog if the kernel was remote,
552 # and a dialog if the kernel was remote,
550 # so we don't suddenly clear the qtconsole without asking.
553 # so we don't suddenly clear the qtconsole without asking.
551 if self._local_kernel:
554 if self._local_kernel:
552 self.exit_requested.emit(self)
555 self.exit_requested.emit(self)
553 else:
556 else:
554 title = self.window().windowTitle()
557 title = self.window().windowTitle()
555 reply = QtGui.QMessageBox.question(self, title,
558 reply = QtGui.QMessageBox.question(self, title,
556 "Kernel has been shutdown permanently. "
559 "Kernel has been shutdown permanently. "
557 "Close the Console?",
560 "Close the Console?",
558 QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
561 QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
559 if reply == QtGui.QMessageBox.Yes:
562 if reply == QtGui.QMessageBox.Yes:
560 self.exit_requested.emit(self)
563 self.exit_requested.emit(self)
561
564
562 def _handle_status(self, msg):
565 def _handle_status(self, msg):
563 """Handle status message"""
566 """Handle status message"""
564 # This is where a busy/idle indicator would be triggered,
567 # This is where a busy/idle indicator would be triggered,
565 # when we make one.
568 # when we make one.
566 state = msg['content'].get('execution_state', '')
569 state = msg['content'].get('execution_state', '')
567 if state == 'starting':
570 if state == 'starting':
568 # kernel started while we were running
571 # kernel started while we were running
569 if self._executing:
572 if self._executing:
570 self._handle_kernel_restarted(died=True)
573 self._handle_kernel_restarted(died=True)
571 elif state == 'idle':
574 elif state == 'idle':
572 pass
575 pass
573 elif state == 'busy':
576 elif state == 'busy':
574 pass
577 pass
575
578
576 def _started_channels(self):
579 def _started_channels(self):
577 """ Called when the KernelManager channels have started listening or
580 """ Called when the KernelManager channels have started listening or
578 when the frontend is assigned an already listening KernelManager.
581 when the frontend is assigned an already listening KernelManager.
579 """
582 """
580 self.reset(clear=True)
583 self.reset(clear=True)
581
584
582 #---------------------------------------------------------------------------
585 #---------------------------------------------------------------------------
583 # 'FrontendWidget' public interface
586 # 'FrontendWidget' public interface
584 #---------------------------------------------------------------------------
587 #---------------------------------------------------------------------------
585
588
586 def copy_raw(self):
589 def copy_raw(self):
587 """ Copy the currently selected text to the clipboard without attempting
590 """ Copy the currently selected text to the clipboard without attempting
588 to remove prompts or otherwise alter the text.
591 to remove prompts or otherwise alter the text.
589 """
592 """
590 self._control.copy()
593 self._control.copy()
591
594
592 def execute_file(self, path, hidden=False):
595 def execute_file(self, path, hidden=False):
593 """ Attempts to execute file with 'path'. If 'hidden', no output is
596 """ Attempts to execute file with 'path'. If 'hidden', no output is
594 shown.
597 shown.
595 """
598 """
596 self.execute('execfile(%r)' % path, hidden=hidden)
599 self.execute('execfile(%r)' % path, hidden=hidden)
597
600
598 def interrupt_kernel(self):
601 def interrupt_kernel(self):
599 """ Attempts to interrupt the running kernel.
602 """ Attempts to interrupt the running kernel.
600
603
601 Also unsets _reading flag, to avoid runtime errors
604 Also unsets _reading flag, to avoid runtime errors
602 if raw_input is called again.
605 if raw_input is called again.
603 """
606 """
604 if self.custom_interrupt:
607 if self.custom_interrupt:
605 self._reading = False
608 self._reading = False
606 self.custom_interrupt_requested.emit()
609 self.custom_interrupt_requested.emit()
607 elif self.kernel_manager:
610 elif self.kernel_manager:
608 self._reading = False
611 self._reading = False
609 self.kernel_manager.interrupt_kernel()
612 self.kernel_manager.interrupt_kernel()
610 else:
613 else:
611 self._append_plain_text('Cannot interrupt a kernel I did not start.\n')
614 self._append_plain_text('Cannot interrupt a kernel I did not start.\n')
612
615
613 def reset(self, clear=False):
616 def reset(self, clear=False):
614 """ Resets the widget to its initial state if ``clear`` parameter
617 """ Resets the widget to its initial state if ``clear`` parameter
615 is True, otherwise
618 is True, otherwise
616 prints a visual indication of the fact that the kernel restarted, but
619 prints a visual indication of the fact that the kernel restarted, but
617 does not clear the traces from previous usage of the kernel before it
620 does not clear the traces from previous usage of the kernel before it
618 was restarted. With ``clear=True``, it is similar to ``%clear``, but
621 was restarted. With ``clear=True``, it is similar to ``%clear``, but
619 also re-writes the banner and aborts execution if necessary.
622 also re-writes the banner and aborts execution if necessary.
620 """
623 """
621 if self._executing:
624 if self._executing:
622 self._executing = False
625 self._executing = False
623 self._request_info['execute'] = {}
626 self._request_info['execute'] = {}
624 self._reading = False
627 self._reading = False
625 self._highlighter.highlighting_on = False
628 self._highlighter.highlighting_on = False
626
629
627 if clear:
630 if clear:
628 self._control.clear()
631 self._control.clear()
629 self._append_plain_text(self.banner)
632 self._append_plain_text(self.banner)
630 # update output marker for stdout/stderr, so that startup
633 # update output marker for stdout/stderr, so that startup
631 # messages appear after banner:
634 # messages appear after banner:
632 self._append_before_prompt_pos = self._get_cursor().position()
635 self._append_before_prompt_pos = self._get_cursor().position()
633 self._show_interpreter_prompt()
636 self._show_interpreter_prompt()
634
637
635 def restart_kernel(self, message, now=False):
638 def restart_kernel(self, message, now=False):
636 """ Attempts to restart the running kernel.
639 """ Attempts to restart the running kernel.
637 """
640 """
638 # FIXME: now should be configurable via a checkbox in the dialog. Right
641 # FIXME: now should be configurable via a checkbox in the dialog. Right
639 # now at least the heartbeat path sets it to True and the manual restart
642 # now at least the heartbeat path sets it to True and the manual restart
640 # to False. But those should just be the pre-selected states of a
643 # to False. But those should just be the pre-selected states of a
641 # checkbox that the user could override if so desired. But I don't know
644 # checkbox that the user could override if so desired. But I don't know
642 # enough Qt to go implementing the checkbox now.
645 # enough Qt to go implementing the checkbox now.
643
646
644 if self.custom_restart:
647 if self.custom_restart:
645 self.custom_restart_requested.emit()
648 self.custom_restart_requested.emit()
646 return
649 return
647
650
648 if self.kernel_manager:
651 if self.kernel_manager:
649 # Pause the heart beat channel to prevent further warnings.
652 # Pause the heart beat channel to prevent further warnings.
650 self.kernel_client.hb_channel.pause()
653 self.kernel_client.hb_channel.pause()
651
654
652 # Prompt the user to restart the kernel. Un-pause the heartbeat if
655 # Prompt the user to restart the kernel. Un-pause the heartbeat if
653 # they decline. (If they accept, the heartbeat will be un-paused
656 # they decline. (If they accept, the heartbeat will be un-paused
654 # automatically when the kernel is restarted.)
657 # automatically when the kernel is restarted.)
655 if self.confirm_restart:
658 if self.confirm_restart:
656 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
659 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
657 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
660 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
658 message, buttons)
661 message, buttons)
659 do_restart = result == QtGui.QMessageBox.Yes
662 do_restart = result == QtGui.QMessageBox.Yes
660 else:
663 else:
661 # confirm_restart is False, so we don't need to ask user
664 # confirm_restart is False, so we don't need to ask user
662 # anything, just do the restart
665 # anything, just do the restart
663 do_restart = True
666 do_restart = True
664 if do_restart:
667 if do_restart:
665 try:
668 try:
666 self.kernel_manager.restart_kernel(now=now)
669 self.kernel_manager.restart_kernel(now=now)
667 except RuntimeError as e:
670 except RuntimeError as e:
668 self._append_plain_text(
671 self._append_plain_text(
669 'Error restarting kernel: %s\n' % e,
672 'Error restarting kernel: %s\n' % e,
670 before_prompt=True
673 before_prompt=True
671 )
674 )
672 else:
675 else:
673 self._append_html("<br>Restarting kernel...\n<hr><br>",
676 self._append_html("<br>Restarting kernel...\n<hr><br>",
674 before_prompt=True,
677 before_prompt=True,
675 )
678 )
676 else:
679 else:
677 self.kernel_client.hb_channel.unpause()
680 self.kernel_client.hb_channel.unpause()
678
681
679 else:
682 else:
680 self._append_plain_text(
683 self._append_plain_text(
681 'Cannot restart a Kernel I did not start\n',
684 'Cannot restart a Kernel I did not start\n',
682 before_prompt=True
685 before_prompt=True
683 )
686 )
684
687
685 #---------------------------------------------------------------------------
688 #---------------------------------------------------------------------------
686 # 'FrontendWidget' protected interface
689 # 'FrontendWidget' protected interface
687 #---------------------------------------------------------------------------
690 #---------------------------------------------------------------------------
688
691
689 def _call_tip(self):
692 def _call_tip(self):
690 """ Shows a call tip, if appropriate, at the current cursor location.
693 """ Shows a call tip, if appropriate, at the current cursor location.
691 """
694 """
692 # Decide if it makes sense to show a call tip
695 # Decide if it makes sense to show a call tip
693 if not self.enable_calltips:
696 if not self.enable_calltips:
694 return False
697 return False
695 cursor = self._get_cursor()
698 cursor = self._get_cursor()
696 cursor.movePosition(QtGui.QTextCursor.Left)
699 cursor.movePosition(QtGui.QTextCursor.Left)
697 if cursor.document().characterAt(cursor.position()) != '(':
700 if cursor.document().characterAt(cursor.position()) != '(':
698 return False
701 return False
699 context = self._get_context(cursor)
702 context = self._get_context(cursor)
700 if not context:
703 if not context:
701 return False
704 return False
702
705
703 # Send the metadata request to the kernel
706 # Send the metadata request to the kernel
704 name = '.'.join(context)
707 name = '.'.join(context)
705 msg_id = self.kernel_client.object_info(name)
708 msg_id = self.kernel_client.object_info(name)
706 pos = self._get_cursor().position()
709 pos = self._get_cursor().position()
707 self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos)
710 self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos)
708 return True
711 return True
709
712
710 def _complete(self):
713 def _complete(self):
711 """ Performs completion at the current cursor location.
714 """ Performs completion at the current cursor location.
712 """
715 """
713 context = self._get_context()
716 context = self._get_context()
714 if context:
717 if context:
715 # Send the completion request to the kernel
718 # Send the completion request to the kernel
716 msg_id = self.kernel_client.complete(
719 msg_id = self.kernel_client.complete(
717 '.'.join(context), # text
720 '.'.join(context), # text
718 self._get_input_buffer_cursor_line(), # line
721 self._get_input_buffer_cursor_line(), # line
719 self._get_input_buffer_cursor_column(), # cursor_pos
722 self._get_input_buffer_cursor_column(), # cursor_pos
720 self.input_buffer) # block
723 self.input_buffer) # block
721 pos = self._get_cursor().position()
724 pos = self._get_cursor().position()
722 info = self._CompletionRequest(msg_id, pos)
725 info = self._CompletionRequest(msg_id, pos)
723 self._request_info['complete'] = info
726 self._request_info['complete'] = info
724
727
725 def _get_context(self, cursor=None):
728 def _get_context(self, cursor=None):
726 """ Gets the context for the specified cursor (or the current cursor
729 """ Gets the context for the specified cursor (or the current cursor
727 if none is specified).
730 if none is specified).
728 """
731 """
729 if cursor is None:
732 if cursor is None:
730 cursor = self._get_cursor()
733 cursor = self._get_cursor()
731 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
734 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
732 QtGui.QTextCursor.KeepAnchor)
735 QtGui.QTextCursor.KeepAnchor)
733 text = cursor.selection().toPlainText()
736 text = cursor.selection().toPlainText()
734 return self._completion_lexer.get_context(text)
737 return self._completion_lexer.get_context(text)
735
738
736 def _process_execute_abort(self, msg):
739 def _process_execute_abort(self, msg):
737 """ Process a reply for an aborted execution request.
740 """ Process a reply for an aborted execution request.
738 """
741 """
739 self._append_plain_text("ERROR: execution aborted\n")
742 self._append_plain_text("ERROR: execution aborted\n")
740
743
741 def _process_execute_error(self, msg):
744 def _process_execute_error(self, msg):
742 """ Process a reply for an execution request that resulted in an error.
745 """ Process a reply for an execution request that resulted in an error.
743 """
746 """
744 content = msg['content']
747 content = msg['content']
745 # If a SystemExit is passed along, this means exit() was called - also
748 # If a SystemExit is passed along, this means exit() was called - also
746 # all the ipython %exit magic syntax of '-k' to be used to keep
749 # all the ipython %exit magic syntax of '-k' to be used to keep
747 # the kernel running
750 # the kernel running
748 if content['ename']=='SystemExit':
751 if content['ename']=='SystemExit':
749 keepkernel = content['evalue']=='-k' or content['evalue']=='True'
752 keepkernel = content['evalue']=='-k' or content['evalue']=='True'
750 self._keep_kernel_on_exit = keepkernel
753 self._keep_kernel_on_exit = keepkernel
751 self.exit_requested.emit(self)
754 self.exit_requested.emit(self)
752 else:
755 else:
753 traceback = ''.join(content['traceback'])
756 traceback = ''.join(content['traceback'])
754 self._append_plain_text(traceback)
757 self._append_plain_text(traceback)
755
758
756 def _process_execute_ok(self, msg):
759 def _process_execute_ok(self, msg):
757 """ Process a reply for a successful execution request.
760 """ Process a reply for a successful execution request.
758 """
761 """
759 payload = msg['content']['payload']
762 payload = msg['content']['payload']
760 for item in payload:
763 for item in payload:
761 if not self._process_execute_payload(item):
764 if not self._process_execute_payload(item):
762 warning = 'Warning: received unknown payload of type %s'
765 warning = 'Warning: received unknown payload of type %s'
763 print(warning % repr(item['source']))
766 print(warning % repr(item['source']))
764
767
765 def _process_execute_payload(self, item):
768 def _process_execute_payload(self, item):
766 """ Process a single payload item from the list of payload items in an
769 """ Process a single payload item from the list of payload items in an
767 execution reply. Returns whether the payload was handled.
770 execution reply. Returns whether the payload was handled.
768 """
771 """
769 # The basic FrontendWidget doesn't handle payloads, as they are a
772 # The basic FrontendWidget doesn't handle payloads, as they are a
770 # mechanism for going beyond the standard Python interpreter model.
773 # mechanism for going beyond the standard Python interpreter model.
771 return False
774 return False
772
775
773 def _show_interpreter_prompt(self):
776 def _show_interpreter_prompt(self):
774 """ Shows a prompt for the interpreter.
777 """ Shows a prompt for the interpreter.
775 """
778 """
776 self._show_prompt('>>> ')
779 self._show_prompt('>>> ')
777
780
778 def _show_interpreter_prompt_for_reply(self, msg):
781 def _show_interpreter_prompt_for_reply(self, msg):
779 """ Shows a prompt for the interpreter given an 'execute_reply' message.
782 """ Shows a prompt for the interpreter given an 'execute_reply' message.
780 """
783 """
781 self._show_interpreter_prompt()
784 self._show_interpreter_prompt()
782
785
783 #------ Signal handlers ----------------------------------------------------
786 #------ Signal handlers ----------------------------------------------------
784
787
785 def _document_contents_change(self, position, removed, added):
788 def _document_contents_change(self, position, removed, added):
786 """ Called whenever the document's content changes. Display a call tip
789 """ Called whenever the document's content changes. Display a call tip
787 if appropriate.
790 if appropriate.
788 """
791 """
789 # Calculate where the cursor should be *after* the change:
792 # Calculate where the cursor should be *after* the change:
790 position += added
793 position += added
791
794
792 document = self._control.document()
795 document = self._control.document()
793 if position == self._get_cursor().position():
796 if position == self._get_cursor().position():
794 self._call_tip()
797 self._call_tip()
795
798
796 #------ Trait default initializers -----------------------------------------
799 #------ Trait default initializers -----------------------------------------
797
800
798 def _banner_default(self):
801 def _banner_default(self):
799 """ Returns the standard Python banner.
802 """ Returns the standard Python banner.
800 """
803 """
801 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
804 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
802 '"license" for more information.'
805 '"license" for more information.'
803 return banner % (sys.version, sys.platform)
806 return banner % (sys.version, sys.platform)
@@ -1,1071 +1,1071 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Sphinx directive to support embedded IPython code.
3 Sphinx directive to support embedded IPython code.
4
4
5 This directive allows pasting of entire interactive IPython sessions, prompts
5 This directive allows pasting of entire interactive IPython sessions, prompts
6 and all, and their code will actually get re-executed at doc build time, with
6 and all, and their code will actually get re-executed at doc build time, with
7 all prompts renumbered sequentially. It also allows you to input code as a pure
7 all prompts renumbered sequentially. It also allows you to input code as a pure
8 python input by giving the argument python to the directive. The output looks
8 python input by giving the argument python to the directive. The output looks
9 like an interactive ipython section.
9 like an interactive ipython section.
10
10
11 To enable this directive, simply list it in your Sphinx ``conf.py`` file
11 To enable this directive, simply list it in your Sphinx ``conf.py`` file
12 (making sure the directory where you placed it is visible to sphinx, as is
12 (making sure the directory where you placed it is visible to sphinx, as is
13 needed for all Sphinx directives). For example, to enable syntax highlighting
13 needed for all Sphinx directives). For example, to enable syntax highlighting
14 and the IPython directive::
14 and the IPython directive::
15
15
16 extensions = ['IPython.sphinxext.ipython_console_highlighting',
16 extensions = ['IPython.sphinxext.ipython_console_highlighting',
17 'IPython.sphinxext.ipython_directive']
17 'IPython.sphinxext.ipython_directive']
18
18
19 The IPython directive outputs code-blocks with the language 'ipython'. So
19 The IPython directive outputs code-blocks with the language 'ipython'. So
20 if you do not have the syntax highlighting extension enabled as well, then
20 if you do not have the syntax highlighting extension enabled as well, then
21 all rendered code-blocks will be uncolored. By default this directive assumes
21 all rendered code-blocks will be uncolored. By default this directive assumes
22 that your prompts are unchanged IPython ones, but this can be customized.
22 that your prompts are unchanged IPython ones, but this can be customized.
23 The configurable options that can be placed in conf.py are:
23 The configurable options that can be placed in conf.py are:
24
24
25 ipython_savefig_dir:
25 ipython_savefig_dir:
26 The directory in which to save the figures. This is relative to the
26 The directory in which to save the figures. This is relative to the
27 Sphinx source directory. The default is `html_static_path`.
27 Sphinx source directory. The default is `html_static_path`.
28 ipython_rgxin:
28 ipython_rgxin:
29 The compiled regular expression to denote the start of IPython input
29 The compiled regular expression to denote the start of IPython input
30 lines. The default is re.compile('In \[(\d+)\]:\s?(.*)\s*'). You
30 lines. The default is re.compile('In \[(\d+)\]:\s?(.*)\s*'). You
31 shouldn't need to change this.
31 shouldn't need to change this.
32 ipython_rgxout:
32 ipython_rgxout:
33 The compiled regular expression to denote the start of IPython output
33 The compiled regular expression to denote the start of IPython output
34 lines. The default is re.compile('Out\[(\d+)\]:\s?(.*)\s*'). You
34 lines. The default is re.compile('Out\[(\d+)\]:\s?(.*)\s*'). You
35 shouldn't need to change this.
35 shouldn't need to change this.
36 ipython_promptin:
36 ipython_promptin:
37 The string to represent the IPython input prompt in the generated ReST.
37 The string to represent the IPython input prompt in the generated ReST.
38 The default is 'In [%d]:'. This expects that the line numbers are used
38 The default is 'In [%d]:'. This expects that the line numbers are used
39 in the prompt.
39 in the prompt.
40 ipython_promptout:
40 ipython_promptout:
41 The string to represent the IPython prompt in the generated ReST. The
41 The string to represent the IPython prompt in the generated ReST. The
42 default is 'Out [%d]:'. This expects that the line numbers are used
42 default is 'Out [%d]:'. This expects that the line numbers are used
43 in the prompt.
43 in the prompt.
44 ipython_mplbackend:
44 ipython_mplbackend:
45 The string which specifies if the embedded Sphinx shell should import
45 The string which specifies if the embedded Sphinx shell should import
46 Matplotlib and set the backend. The value specifies a backend that is
46 Matplotlib and set the backend. The value specifies a backend that is
47 passed to `matplotlib.use()` before any lines in `ipython_execlines` are
47 passed to `matplotlib.use()` before any lines in `ipython_execlines` are
48 executed. If not specified in conf.py, then the default value of 'agg' is
48 executed. If not specified in conf.py, then the default value of 'agg' is
49 used. To use the IPython directive without matplotlib as a dependency, set
49 used. To use the IPython directive without matplotlib as a dependency, set
50 the value to `None`. It may end up that matplotlib is still imported
50 the value to `None`. It may end up that matplotlib is still imported
51 if the user specifies so in `ipython_execlines` or makes use of the
51 if the user specifies so in `ipython_execlines` or makes use of the
52 @savefig pseudo decorator.
52 @savefig pseudo decorator.
53 ipython_execlines:
53 ipython_execlines:
54 A list of strings to be exec'd in the embedded Sphinx shell. Typical
54 A list of strings to be exec'd in the embedded Sphinx shell. Typical
55 usage is to make certain packages always available. Set this to an empty
55 usage is to make certain packages always available. Set this to an empty
56 list if you wish to have no imports always available. If specified in
56 list if you wish to have no imports always available. If specified in
57 conf.py as `None`, then it has the effect of making no imports available.
57 conf.py as `None`, then it has the effect of making no imports available.
58 If omitted from conf.py altogether, then the default value of
58 If omitted from conf.py altogether, then the default value of
59 ['import numpy as np', 'import matplotlib.pyplot as plt'] is used.
59 ['import numpy as np', 'import matplotlib.pyplot as plt'] is used.
60 ipython_holdcount
60 ipython_holdcount
61 When the @suppress pseudo-decorator is used, the execution count can be
61 When the @suppress pseudo-decorator is used, the execution count can be
62 incremented or not. The default behavior is to hold the execution count,
62 incremented or not. The default behavior is to hold the execution count,
63 corresponding to a value of `True`. Set this to `False` to increment
63 corresponding to a value of `True`. Set this to `False` to increment
64 the execution count after each suppressed command.
64 the execution count after each suppressed command.
65
65
66 As an example, to use the IPython directive when `matplotlib` is not available,
66 As an example, to use the IPython directive when `matplotlib` is not available,
67 one sets the backend to `None`::
67 one sets the backend to `None`::
68
68
69 ipython_mplbackend = None
69 ipython_mplbackend = None
70
70
71 An example usage of the directive is:
71 An example usage of the directive is:
72
72
73 .. code-block:: rst
73 .. code-block:: rst
74
74
75 .. ipython::
75 .. ipython::
76
76
77 In [1]: x = 1
77 In [1]: x = 1
78
78
79 In [2]: y = x**2
79 In [2]: y = x**2
80
80
81 In [3]: print(y)
81 In [3]: print(y)
82
82
83 See http://matplotlib.org/sampledoc/ipython_directive.html for additional
83 See http://matplotlib.org/sampledoc/ipython_directive.html for additional
84 documentation.
84 documentation.
85
85
86 Pseudo-Decorators
86 Pseudo-Decorators
87 =================
87 =================
88
88
89 In addition to the Pseudo-Decorators/options described at the above link,
89 In addition to the Pseudo-Decorators/options described at the above link,
90 several enhancements have been made.
90 several enhancements have been made.
91 The directive will emit a message to the console at build-time if
91 The directive will emit a message to the console at build-time if
92 code-execution resulted in an exception or warning. You can suppress these on
92 code-execution resulted in an exception or warning. You can suppress these on
93 a per-block basis by specifying the :okexcept: or :okwarning: options:
93 a per-block basis by specifying the :okexcept: or :okwarning: options:
94
94
95 .. code-block:: rst
95 .. code-block:: rst
96
96
97 .. ipython::
97 .. ipython::
98 :okexcept:
98 :okexcept:
99 :okwarning:
99 :okwarning:
100
100
101 In [1]: 1/0
101 In [1]: 1/0
102 In [2]: # raise warning.
102 In [2]: # raise warning.
103
103
104 ToDo
104 ToDo
105 ----
105 ----
106
106
107 - Turn the ad-hoc test() function into a real test suite.
107 - Turn the ad-hoc test() function into a real test suite.
108 - Break up ipython-specific functionality from matplotlib stuff into better
108 - Break up ipython-specific functionality from matplotlib stuff into better
109 separated code.
109 separated code.
110
110
111 Authors
111 Authors
112 -------
112 -------
113
113
114 - John D Hunter: orignal author.
114 - John D Hunter: orignal author.
115 - Fernando Perez: refactoring, documentation, cleanups, port to 0.11.
115 - Fernando Perez: refactoring, documentation, cleanups, port to 0.11.
116 - VΓ‘clavΕ milauer <eudoxos-AT-arcig.cz>: Prompt generalizations.
116 - VΓ‘clavΕ milauer <eudoxos-AT-arcig.cz>: Prompt generalizations.
117 - Skipper Seabold, refactoring, cleanups, pure python addition
117 - Skipper Seabold, refactoring, cleanups, pure python addition
118 """
118 """
119 from __future__ import print_function
119 from __future__ import print_function
120
120
121 #-----------------------------------------------------------------------------
121 #-----------------------------------------------------------------------------
122 # Imports
122 # Imports
123 #-----------------------------------------------------------------------------
123 #-----------------------------------------------------------------------------
124
124
125 # Stdlib
125 # Stdlib
126 import os
126 import os
127 import re
127 import re
128 import sys
128 import sys
129 import tempfile
129 import tempfile
130 import ast
130 import ast
131 import warnings
131 import warnings
132
132
133 # To keep compatibility with various python versions
133 # To keep compatibility with various python versions
134 try:
134 try:
135 from hashlib import md5
135 from hashlib import md5
136 except ImportError:
136 except ImportError:
137 from md5 import md5
137 from md5 import md5
138
138
139 # Third-party
139 # Third-party
140 import sphinx
140 import sphinx
141 from docutils.parsers.rst import directives
141 from docutils.parsers.rst import directives
142 from docutils import nodes
142 from docutils import nodes
143 from sphinx.util.compat import Directive
143 from sphinx.util.compat import Directive
144
144
145 # Our own
145 # Our own
146 from IPython import Config, InteractiveShell
146 from IPython import Config, InteractiveShell
147 from IPython.core.profiledir import ProfileDir
147 from IPython.core.profiledir import ProfileDir
148 from IPython.utils import io
148 from IPython.utils import io
149 from IPython.utils.py3compat import PY3
149 from IPython.utils.py3compat import PY3
150
150
151 if PY3:
151 if PY3:
152 from io import StringIO
152 from io import StringIO
153 else:
153 else:
154 from StringIO import StringIO
154 from StringIO import StringIO
155
155
156 #-----------------------------------------------------------------------------
156 #-----------------------------------------------------------------------------
157 # Globals
157 # Globals
158 #-----------------------------------------------------------------------------
158 #-----------------------------------------------------------------------------
159 # for tokenizing blocks
159 # for tokenizing blocks
160 COMMENT, INPUT, OUTPUT = range(3)
160 COMMENT, INPUT, OUTPUT = range(3)
161
161
162 #-----------------------------------------------------------------------------
162 #-----------------------------------------------------------------------------
163 # Functions and class declarations
163 # Functions and class declarations
164 #-----------------------------------------------------------------------------
164 #-----------------------------------------------------------------------------
165
165
166 def block_parser(part, rgxin, rgxout, fmtin, fmtout):
166 def block_parser(part, rgxin, rgxout, fmtin, fmtout):
167 """
167 """
168 part is a string of ipython text, comprised of at most one
168 part is a string of ipython text, comprised of at most one
169 input, one ouput, comments, and blank lines. The block parser
169 input, one ouput, comments, and blank lines. The block parser
170 parses the text into a list of::
170 parses the text into a list of::
171
171
172 blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...]
172 blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...]
173
173
174 where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and
174 where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and
175 data is, depending on the type of token::
175 data is, depending on the type of token::
176
176
177 COMMENT : the comment string
177 COMMENT : the comment string
178
178
179 INPUT: the (DECORATOR, INPUT_LINE, REST) where
179 INPUT: the (DECORATOR, INPUT_LINE, REST) where
180 DECORATOR: the input decorator (or None)
180 DECORATOR: the input decorator (or None)
181 INPUT_LINE: the input as string (possibly multi-line)
181 INPUT_LINE: the input as string (possibly multi-line)
182 REST : any stdout generated by the input line (not OUTPUT)
182 REST : any stdout generated by the input line (not OUTPUT)
183
183
184 OUTPUT: the output string, possibly multi-line
184 OUTPUT: the output string, possibly multi-line
185
185
186 """
186 """
187 block = []
187 block = []
188 lines = part.split('\n')
188 lines = part.split('\n')
189 N = len(lines)
189 N = len(lines)
190 i = 0
190 i = 0
191 decorator = None
191 decorator = None
192 while 1:
192 while 1:
193
193
194 if i==N:
194 if i==N:
195 # nothing left to parse -- the last line
195 # nothing left to parse -- the last line
196 break
196 break
197
197
198 line = lines[i]
198 line = lines[i]
199 i += 1
199 i += 1
200 line_stripped = line.strip()
200 line_stripped = line.strip()
201 if line_stripped.startswith('#'):
201 if line_stripped.startswith('#'):
202 block.append((COMMENT, line))
202 block.append((COMMENT, line))
203 continue
203 continue
204
204
205 if line_stripped.startswith('@'):
205 if line_stripped.startswith('@'):
206 # we're assuming at most one decorator -- may need to
206 # we're assuming at most one decorator -- may need to
207 # rethink
207 # rethink
208 decorator = line_stripped
208 decorator = line_stripped
209 continue
209 continue
210
210
211 # does this look like an input line?
211 # does this look like an input line?
212 matchin = rgxin.match(line)
212 matchin = rgxin.match(line)
213 if matchin:
213 if matchin:
214 lineno, inputline = int(matchin.group(1)), matchin.group(2)
214 lineno, inputline = int(matchin.group(1)), matchin.group(2)
215
215
216 # the ....: continuation string
216 # the ....: continuation string
217 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
217 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
218 Nc = len(continuation)
218 Nc = len(continuation)
219 # input lines can continue on for more than one line, if
219 # input lines can continue on for more than one line, if
220 # we have a '\' line continuation char or a function call
220 # we have a '\' line continuation char or a function call
221 # echo line 'print'. The input line can only be
221 # echo line 'print'. The input line can only be
222 # terminated by the end of the block or an output line, so
222 # terminated by the end of the block or an output line, so
223 # we parse out the rest of the input line if it is
223 # we parse out the rest of the input line if it is
224 # multiline as well as any echo text
224 # multiline as well as any echo text
225
225
226 rest = []
226 rest = []
227 while i<N:
227 while i<N:
228
228
229 # look ahead; if the next line is blank, or a comment, or
229 # look ahead; if the next line is blank, or a comment, or
230 # an output line, we're done
230 # an output line, we're done
231
231
232 nextline = lines[i]
232 nextline = lines[i]
233 matchout = rgxout.match(nextline)
233 matchout = rgxout.match(nextline)
234 #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation))
234 #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation))
235 if matchout or nextline.startswith('#'):
235 if matchout or nextline.startswith('#'):
236 break
236 break
237 elif nextline.startswith(continuation):
237 elif nextline.startswith(continuation):
238 # The default ipython_rgx* treat the space following the colon as optional.
238 # The default ipython_rgx* treat the space following the colon as optional.
239 # However, If the space is there we must consume it or code
239 # However, If the space is there we must consume it or code
240 # employing the cython_magic extension will fail to execute.
240 # employing the cython_magic extension will fail to execute.
241 #
241 #
242 # This works with the default ipython_rgx* patterns,
242 # This works with the default ipython_rgx* patterns,
243 # If you modify them, YMMV.
243 # If you modify them, YMMV.
244 nextline = nextline[Nc:]
244 nextline = nextline[Nc:]
245 if nextline and nextline[0] == ' ':
245 if nextline and nextline[0] == ' ':
246 nextline = nextline[1:]
246 nextline = nextline[1:]
247
247
248 inputline += '\n' + nextline
248 inputline += '\n' + nextline
249 else:
249 else:
250 rest.append(nextline)
250 rest.append(nextline)
251 i+= 1
251 i+= 1
252
252
253 block.append((INPUT, (decorator, inputline, '\n'.join(rest))))
253 block.append((INPUT, (decorator, inputline, '\n'.join(rest))))
254 continue
254 continue
255
255
256 # if it looks like an output line grab all the text to the end
256 # if it looks like an output line grab all the text to the end
257 # of the block
257 # of the block
258 matchout = rgxout.match(line)
258 matchout = rgxout.match(line)
259 if matchout:
259 if matchout:
260 lineno, output = int(matchout.group(1)), matchout.group(2)
260 lineno, output = int(matchout.group(1)), matchout.group(2)
261 if i<N-1:
261 if i<N-1:
262 output = '\n'.join([output] + lines[i:])
262 output = '\n'.join([output] + lines[i:])
263
263
264 block.append((OUTPUT, output))
264 block.append((OUTPUT, output))
265 break
265 break
266
266
267 return block
267 return block
268
268
269
269
270 class EmbeddedSphinxShell(object):
270 class EmbeddedSphinxShell(object):
271 """An embedded IPython instance to run inside Sphinx"""
271 """An embedded IPython instance to run inside Sphinx"""
272
272
273 def __init__(self, exec_lines=None):
273 def __init__(self, exec_lines=None):
274
274
275 self.cout = StringIO()
275 self.cout = StringIO()
276
276
277 if exec_lines is None:
277 if exec_lines is None:
278 exec_lines = []
278 exec_lines = []
279
279
280 # Create config object for IPython
280 # Create config object for IPython
281 config = Config()
281 config = Config()
282 config.InteractiveShell.autocall = False
282 config.InteractiveShell.autocall = False
283 config.InteractiveShell.autoindent = False
283 config.InteractiveShell.autoindent = False
284 config.InteractiveShell.colors = 'NoColor'
284 config.InteractiveShell.colors = 'NoColor'
285
285
286 # create a profile so instance history isn't saved
286 # create a profile so instance history isn't saved
287 tmp_profile_dir = tempfile.mkdtemp(prefix='profile_')
287 tmp_profile_dir = tempfile.mkdtemp(prefix='profile_')
288 profname = 'auto_profile_sphinx_build'
288 profname = 'auto_profile_sphinx_build'
289 pdir = os.path.join(tmp_profile_dir,profname)
289 pdir = os.path.join(tmp_profile_dir,profname)
290 profile = ProfileDir.create_profile_dir(pdir)
290 profile = ProfileDir.create_profile_dir(pdir)
291
291
292 # Create and initialize global ipython, but don't start its mainloop.
292 # Create and initialize global ipython, but don't start its mainloop.
293 # This will persist across different EmbededSphinxShell instances.
293 # This will persist across different EmbededSphinxShell instances.
294 IP = InteractiveShell.instance(config=config, profile_dir=profile)
294 IP = InteractiveShell.instance(config=config, profile_dir=profile)
295
295
296 # io.stdout redirect must be done after instantiating InteractiveShell
296 # io.stdout redirect must be done after instantiating InteractiveShell
297 io.stdout = self.cout
297 io.stdout = self.cout
298 io.stderr = self.cout
298 io.stderr = self.cout
299
299
300 # For debugging, so we can see normal output, use this:
300 # For debugging, so we can see normal output, use this:
301 #from IPython.utils.io import Tee
301 #from IPython.utils.io import Tee
302 #io.stdout = Tee(self.cout, channel='stdout') # dbg
302 #io.stdout = Tee(self.cout, channel='stdout') # dbg
303 #io.stderr = Tee(self.cout, channel='stderr') # dbg
303 #io.stderr = Tee(self.cout, channel='stderr') # dbg
304
304
305 # Store a few parts of IPython we'll need.
305 # Store a few parts of IPython we'll need.
306 self.IP = IP
306 self.IP = IP
307 self.user_ns = self.IP.user_ns
307 self.user_ns = self.IP.user_ns
308 self.user_global_ns = self.IP.user_global_ns
308 self.user_global_ns = self.IP.user_global_ns
309
309
310 self.input = ''
310 self.input = ''
311 self.output = ''
311 self.output = ''
312
312
313 self.is_verbatim = False
313 self.is_verbatim = False
314 self.is_doctest = False
314 self.is_doctest = False
315 self.is_suppress = False
315 self.is_suppress = False
316
316
317 # Optionally, provide more detailed information to shell.
317 # Optionally, provide more detailed information to shell.
318 # this is assigned by the SetUp method of IPythonDirective
318 # this is assigned by the SetUp method of IPythonDirective
319 # to point at itself.
319 # to point at itself.
320 #
320 #
321 # So, you can access handy things at self.directive.state
321 # So, you can access handy things at self.directive.state
322 self.directive = None
322 self.directive = None
323
323
324 # on the first call to the savefig decorator, we'll import
324 # on the first call to the savefig decorator, we'll import
325 # pyplot as plt so we can make a call to the plt.gcf().savefig
325 # pyplot as plt so we can make a call to the plt.gcf().savefig
326 self._pyplot_imported = False
326 self._pyplot_imported = False
327
327
328 # Prepopulate the namespace.
328 # Prepopulate the namespace.
329 for line in exec_lines:
329 for line in exec_lines:
330 self.process_input_line(line, store_history=False)
330 self.process_input_line(line, store_history=False)
331
331
332 def clear_cout(self):
332 def clear_cout(self):
333 self.cout.seek(0)
333 self.cout.seek(0)
334 self.cout.truncate(0)
334 self.cout.truncate(0)
335
335
336 def process_input_line(self, line, store_history=True):
336 def process_input_line(self, line, store_history=True):
337 """process the input, capturing stdout"""
337 """process the input, capturing stdout"""
338
338
339 stdout = sys.stdout
339 stdout = sys.stdout
340 splitter = self.IP.input_splitter
340 splitter = self.IP.input_splitter
341 try:
341 try:
342 sys.stdout = self.cout
342 sys.stdout = self.cout
343 splitter.push(line)
343 splitter.push(line)
344 more = splitter.push_accepts_more()
344 more = splitter.push_accepts_more()
345 if not more:
345 if not more:
346 source_raw = splitter.source_raw_reset()[1]
346 source_raw = splitter.raw_reset()
347 self.IP.run_cell(source_raw, store_history=store_history)
347 self.IP.run_cell(source_raw, store_history=store_history)
348 finally:
348 finally:
349 sys.stdout = stdout
349 sys.stdout = stdout
350
350
351 def process_image(self, decorator):
351 def process_image(self, decorator):
352 """
352 """
353 # build out an image directive like
353 # build out an image directive like
354 # .. image:: somefile.png
354 # .. image:: somefile.png
355 # :width 4in
355 # :width 4in
356 #
356 #
357 # from an input like
357 # from an input like
358 # savefig somefile.png width=4in
358 # savefig somefile.png width=4in
359 """
359 """
360 savefig_dir = self.savefig_dir
360 savefig_dir = self.savefig_dir
361 source_dir = self.source_dir
361 source_dir = self.source_dir
362 saveargs = decorator.split(' ')
362 saveargs = decorator.split(' ')
363 filename = saveargs[1]
363 filename = saveargs[1]
364 # insert relative path to image file in source
364 # insert relative path to image file in source
365 outfile = os.path.relpath(os.path.join(savefig_dir,filename),
365 outfile = os.path.relpath(os.path.join(savefig_dir,filename),
366 source_dir)
366 source_dir)
367
367
368 imagerows = ['.. image:: %s'%outfile]
368 imagerows = ['.. image:: %s'%outfile]
369
369
370 for kwarg in saveargs[2:]:
370 for kwarg in saveargs[2:]:
371 arg, val = kwarg.split('=')
371 arg, val = kwarg.split('=')
372 arg = arg.strip()
372 arg = arg.strip()
373 val = val.strip()
373 val = val.strip()
374 imagerows.append(' :%s: %s'%(arg, val))
374 imagerows.append(' :%s: %s'%(arg, val))
375
375
376 image_file = os.path.basename(outfile) # only return file name
376 image_file = os.path.basename(outfile) # only return file name
377 image_directive = '\n'.join(imagerows)
377 image_directive = '\n'.join(imagerows)
378 return image_file, image_directive
378 return image_file, image_directive
379
379
380 # Callbacks for each type of token
380 # Callbacks for each type of token
381 def process_input(self, data, input_prompt, lineno):
381 def process_input(self, data, input_prompt, lineno):
382 """
382 """
383 Process data block for INPUT token.
383 Process data block for INPUT token.
384
384
385 """
385 """
386 decorator, input, rest = data
386 decorator, input, rest = data
387 image_file = None
387 image_file = None
388 image_directive = None
388 image_directive = None
389
389
390 is_verbatim = decorator=='@verbatim' or self.is_verbatim
390 is_verbatim = decorator=='@verbatim' or self.is_verbatim
391 is_doctest = (decorator is not None and \
391 is_doctest = (decorator is not None and \
392 decorator.startswith('@doctest')) or self.is_doctest
392 decorator.startswith('@doctest')) or self.is_doctest
393 is_suppress = decorator=='@suppress' or self.is_suppress
393 is_suppress = decorator=='@suppress' or self.is_suppress
394 is_okexcept = decorator=='@okexcept' or self.is_okexcept
394 is_okexcept = decorator=='@okexcept' or self.is_okexcept
395 is_okwarning = decorator=='@okwarning' or self.is_okwarning
395 is_okwarning = decorator=='@okwarning' or self.is_okwarning
396 is_savefig = decorator is not None and \
396 is_savefig = decorator is not None and \
397 decorator.startswith('@savefig')
397 decorator.startswith('@savefig')
398
398
399 input_lines = input.split('\n')
399 input_lines = input.split('\n')
400 if len(input_lines) > 1:
400 if len(input_lines) > 1:
401 if input_lines[-1] != "":
401 if input_lines[-1] != "":
402 input_lines.append('') # make sure there's a blank line
402 input_lines.append('') # make sure there's a blank line
403 # so splitter buffer gets reset
403 # so splitter buffer gets reset
404
404
405 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
405 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
406
406
407 if is_savefig:
407 if is_savefig:
408 image_file, image_directive = self.process_image(decorator)
408 image_file, image_directive = self.process_image(decorator)
409
409
410 ret = []
410 ret = []
411 is_semicolon = False
411 is_semicolon = False
412
412
413 # Hold the execution count, if requested to do so.
413 # Hold the execution count, if requested to do so.
414 if is_suppress and self.hold_count:
414 if is_suppress and self.hold_count:
415 store_history = False
415 store_history = False
416 else:
416 else:
417 store_history = True
417 store_history = True
418
418
419 # Note: catch_warnings is not thread safe
419 # Note: catch_warnings is not thread safe
420 with warnings.catch_warnings(record=True) as ws:
420 with warnings.catch_warnings(record=True) as ws:
421 for i, line in enumerate(input_lines):
421 for i, line in enumerate(input_lines):
422 if line.endswith(';'):
422 if line.endswith(';'):
423 is_semicolon = True
423 is_semicolon = True
424
424
425 if i == 0:
425 if i == 0:
426 # process the first input line
426 # process the first input line
427 if is_verbatim:
427 if is_verbatim:
428 self.process_input_line('')
428 self.process_input_line('')
429 self.IP.execution_count += 1 # increment it anyway
429 self.IP.execution_count += 1 # increment it anyway
430 else:
430 else:
431 # only submit the line in non-verbatim mode
431 # only submit the line in non-verbatim mode
432 self.process_input_line(line, store_history=store_history)
432 self.process_input_line(line, store_history=store_history)
433 formatted_line = '%s %s'%(input_prompt, line)
433 formatted_line = '%s %s'%(input_prompt, line)
434 else:
434 else:
435 # process a continuation line
435 # process a continuation line
436 if not is_verbatim:
436 if not is_verbatim:
437 self.process_input_line(line, store_history=store_history)
437 self.process_input_line(line, store_history=store_history)
438
438
439 formatted_line = '%s %s'%(continuation, line)
439 formatted_line = '%s %s'%(continuation, line)
440
440
441 if not is_suppress:
441 if not is_suppress:
442 ret.append(formatted_line)
442 ret.append(formatted_line)
443
443
444 if not is_suppress and len(rest.strip()) and is_verbatim:
444 if not is_suppress and len(rest.strip()) and is_verbatim:
445 # the "rest" is the standard output of the
445 # the "rest" is the standard output of the
446 # input, which needs to be added in
446 # input, which needs to be added in
447 # verbatim mode
447 # verbatim mode
448 ret.append(rest)
448 ret.append(rest)
449
449
450 self.cout.seek(0)
450 self.cout.seek(0)
451 output = self.cout.read()
451 output = self.cout.read()
452 if not is_suppress and not is_semicolon:
452 if not is_suppress and not is_semicolon:
453 ret.append(output)
453 ret.append(output)
454 elif is_semicolon: # get spacing right
454 elif is_semicolon: # get spacing right
455 ret.append('')
455 ret.append('')
456
456
457 # context information
457 # context information
458 filename = "Unknown"
458 filename = "Unknown"
459 lineno = 0
459 lineno = 0
460 if self.directive.state:
460 if self.directive.state:
461 filename = self.directive.state.document.current_source
461 filename = self.directive.state.document.current_source
462 lineno = self.directive.state.document.current_line
462 lineno = self.directive.state.document.current_line
463
463
464 # output any exceptions raised during execution to stdout
464 # output any exceptions raised during execution to stdout
465 # unless :okexcept: has been specified.
465 # unless :okexcept: has been specified.
466 if not is_okexcept and "Traceback" in output:
466 if not is_okexcept and "Traceback" in output:
467 s = "\nException in %s at block ending on line %s\n" % (filename, lineno)
467 s = "\nException in %s at block ending on line %s\n" % (filename, lineno)
468 s += "Specify :okexcept: as an option in the ipython:: block to suppress this message\n"
468 s += "Specify :okexcept: as an option in the ipython:: block to suppress this message\n"
469 sys.stdout.write('\n\n>>>' + ('-' * 73))
469 sys.stdout.write('\n\n>>>' + ('-' * 73))
470 sys.stdout.write(s)
470 sys.stdout.write(s)
471 sys.stdout.write(output)
471 sys.stdout.write(output)
472 sys.stdout.write('<<<' + ('-' * 73) + '\n\n')
472 sys.stdout.write('<<<' + ('-' * 73) + '\n\n')
473
473
474 # output any warning raised during execution to stdout
474 # output any warning raised during execution to stdout
475 # unless :okwarning: has been specified.
475 # unless :okwarning: has been specified.
476 if not is_okwarning:
476 if not is_okwarning:
477 for w in ws:
477 for w in ws:
478 s = "\nWarning in %s at block ending on line %s\n" % (filename, lineno)
478 s = "\nWarning in %s at block ending on line %s\n" % (filename, lineno)
479 s += "Specify :okwarning: as an option in the ipython:: block to suppress this message\n"
479 s += "Specify :okwarning: as an option in the ipython:: block to suppress this message\n"
480 sys.stdout.write('\n\n>>>' + ('-' * 73))
480 sys.stdout.write('\n\n>>>' + ('-' * 73))
481 sys.stdout.write(s)
481 sys.stdout.write(s)
482 sys.stdout.write(('-' * 76) + '\n')
482 sys.stdout.write(('-' * 76) + '\n')
483 s=warnings.formatwarning(w.message, w.category,
483 s=warnings.formatwarning(w.message, w.category,
484 w.filename, w.lineno, w.line)
484 w.filename, w.lineno, w.line)
485 sys.stdout.write(s)
485 sys.stdout.write(s)
486 sys.stdout.write('<<<' + ('-' * 73) + '\n')
486 sys.stdout.write('<<<' + ('-' * 73) + '\n')
487
487
488 self.cout.truncate(0)
488 self.cout.truncate(0)
489 return (ret, input_lines, output, is_doctest, decorator, image_file,
489 return (ret, input_lines, output, is_doctest, decorator, image_file,
490 image_directive)
490 image_directive)
491
491
492
492
493 def process_output(self, data, output_prompt,
493 def process_output(self, data, output_prompt,
494 input_lines, output, is_doctest, decorator, image_file):
494 input_lines, output, is_doctest, decorator, image_file):
495 """
495 """
496 Process data block for OUTPUT token.
496 Process data block for OUTPUT token.
497
497
498 """
498 """
499 TAB = ' ' * 4
499 TAB = ' ' * 4
500
500
501 if is_doctest and output is not None:
501 if is_doctest and output is not None:
502
502
503 found = output
503 found = output
504 found = found.strip()
504 found = found.strip()
505 submitted = data.strip()
505 submitted = data.strip()
506
506
507 if self.directive is None:
507 if self.directive is None:
508 source = 'Unavailable'
508 source = 'Unavailable'
509 content = 'Unavailable'
509 content = 'Unavailable'
510 else:
510 else:
511 source = self.directive.state.document.current_source
511 source = self.directive.state.document.current_source
512 content = self.directive.content
512 content = self.directive.content
513 # Add tabs and join into a single string.
513 # Add tabs and join into a single string.
514 content = '\n'.join([TAB + line for line in content])
514 content = '\n'.join([TAB + line for line in content])
515
515
516 # Make sure the output contains the output prompt.
516 # Make sure the output contains the output prompt.
517 ind = found.find(output_prompt)
517 ind = found.find(output_prompt)
518 if ind < 0:
518 if ind < 0:
519 e = ('output does not contain output prompt\n\n'
519 e = ('output does not contain output prompt\n\n'
520 'Document source: {0}\n\n'
520 'Document source: {0}\n\n'
521 'Raw content: \n{1}\n\n'
521 'Raw content: \n{1}\n\n'
522 'Input line(s):\n{TAB}{2}\n\n'
522 'Input line(s):\n{TAB}{2}\n\n'
523 'Output line(s):\n{TAB}{3}\n\n')
523 'Output line(s):\n{TAB}{3}\n\n')
524 e = e.format(source, content, '\n'.join(input_lines),
524 e = e.format(source, content, '\n'.join(input_lines),
525 repr(found), TAB=TAB)
525 repr(found), TAB=TAB)
526 raise RuntimeError(e)
526 raise RuntimeError(e)
527 found = found[len(output_prompt):].strip()
527 found = found[len(output_prompt):].strip()
528
528
529 # Handle the actual doctest comparison.
529 # Handle the actual doctest comparison.
530 if decorator.strip() == '@doctest':
530 if decorator.strip() == '@doctest':
531 # Standard doctest
531 # Standard doctest
532 if found != submitted:
532 if found != submitted:
533 e = ('doctest failure\n\n'
533 e = ('doctest failure\n\n'
534 'Document source: {0}\n\n'
534 'Document source: {0}\n\n'
535 'Raw content: \n{1}\n\n'
535 'Raw content: \n{1}\n\n'
536 'On input line(s):\n{TAB}{2}\n\n'
536 'On input line(s):\n{TAB}{2}\n\n'
537 'we found output:\n{TAB}{3}\n\n'
537 'we found output:\n{TAB}{3}\n\n'
538 'instead of the expected:\n{TAB}{4}\n\n')
538 'instead of the expected:\n{TAB}{4}\n\n')
539 e = e.format(source, content, '\n'.join(input_lines),
539 e = e.format(source, content, '\n'.join(input_lines),
540 repr(found), repr(submitted), TAB=TAB)
540 repr(found), repr(submitted), TAB=TAB)
541 raise RuntimeError(e)
541 raise RuntimeError(e)
542 else:
542 else:
543 self.custom_doctest(decorator, input_lines, found, submitted)
543 self.custom_doctest(decorator, input_lines, found, submitted)
544
544
545 def process_comment(self, data):
545 def process_comment(self, data):
546 """Process data fPblock for COMMENT token."""
546 """Process data fPblock for COMMENT token."""
547 if not self.is_suppress:
547 if not self.is_suppress:
548 return [data]
548 return [data]
549
549
550 def save_image(self, image_file):
550 def save_image(self, image_file):
551 """
551 """
552 Saves the image file to disk.
552 Saves the image file to disk.
553 """
553 """
554 self.ensure_pyplot()
554 self.ensure_pyplot()
555 command = 'plt.gcf().savefig("%s")'%image_file
555 command = 'plt.gcf().savefig("%s")'%image_file
556 #print 'SAVEFIG', command # dbg
556 #print 'SAVEFIG', command # dbg
557 self.process_input_line('bookmark ipy_thisdir', store_history=False)
557 self.process_input_line('bookmark ipy_thisdir', store_history=False)
558 self.process_input_line('cd -b ipy_savedir', store_history=False)
558 self.process_input_line('cd -b ipy_savedir', store_history=False)
559 self.process_input_line(command, store_history=False)
559 self.process_input_line(command, store_history=False)
560 self.process_input_line('cd -b ipy_thisdir', store_history=False)
560 self.process_input_line('cd -b ipy_thisdir', store_history=False)
561 self.process_input_line('bookmark -d ipy_thisdir', store_history=False)
561 self.process_input_line('bookmark -d ipy_thisdir', store_history=False)
562 self.clear_cout()
562 self.clear_cout()
563
563
564 def process_block(self, block):
564 def process_block(self, block):
565 """
565 """
566 process block from the block_parser and return a list of processed lines
566 process block from the block_parser and return a list of processed lines
567 """
567 """
568 ret = []
568 ret = []
569 output = None
569 output = None
570 input_lines = None
570 input_lines = None
571 lineno = self.IP.execution_count
571 lineno = self.IP.execution_count
572
572
573 input_prompt = self.promptin % lineno
573 input_prompt = self.promptin % lineno
574 output_prompt = self.promptout % lineno
574 output_prompt = self.promptout % lineno
575 image_file = None
575 image_file = None
576 image_directive = None
576 image_directive = None
577
577
578 for token, data in block:
578 for token, data in block:
579 if token == COMMENT:
579 if token == COMMENT:
580 out_data = self.process_comment(data)
580 out_data = self.process_comment(data)
581 elif token == INPUT:
581 elif token == INPUT:
582 (out_data, input_lines, output, is_doctest, decorator,
582 (out_data, input_lines, output, is_doctest, decorator,
583 image_file, image_directive) = \
583 image_file, image_directive) = \
584 self.process_input(data, input_prompt, lineno)
584 self.process_input(data, input_prompt, lineno)
585 elif token == OUTPUT:
585 elif token == OUTPUT:
586 out_data = \
586 out_data = \
587 self.process_output(data, output_prompt,
587 self.process_output(data, output_prompt,
588 input_lines, output, is_doctest,
588 input_lines, output, is_doctest,
589 decorator, image_file)
589 decorator, image_file)
590 if out_data:
590 if out_data:
591 ret.extend(out_data)
591 ret.extend(out_data)
592
592
593 # save the image files
593 # save the image files
594 if image_file is not None:
594 if image_file is not None:
595 self.save_image(image_file)
595 self.save_image(image_file)
596
596
597 return ret, image_directive
597 return ret, image_directive
598
598
599 def ensure_pyplot(self):
599 def ensure_pyplot(self):
600 """
600 """
601 Ensures that pyplot has been imported into the embedded IPython shell.
601 Ensures that pyplot has been imported into the embedded IPython shell.
602
602
603 Also, makes sure to set the backend appropriately if not set already.
603 Also, makes sure to set the backend appropriately if not set already.
604
604
605 """
605 """
606 # We are here if the @figure pseudo decorator was used. Thus, it's
606 # We are here if the @figure pseudo decorator was used. Thus, it's
607 # possible that we could be here even if python_mplbackend were set to
607 # possible that we could be here even if python_mplbackend were set to
608 # `None`. That's also strange and perhaps worthy of raising an
608 # `None`. That's also strange and perhaps worthy of raising an
609 # exception, but for now, we just set the backend to 'agg'.
609 # exception, but for now, we just set the backend to 'agg'.
610
610
611 if not self._pyplot_imported:
611 if not self._pyplot_imported:
612 if 'matplotlib.backends' not in sys.modules:
612 if 'matplotlib.backends' not in sys.modules:
613 # Then ipython_matplotlib was set to None but there was a
613 # Then ipython_matplotlib was set to None but there was a
614 # call to the @figure decorator (and ipython_execlines did
614 # call to the @figure decorator (and ipython_execlines did
615 # not set a backend).
615 # not set a backend).
616 #raise Exception("No backend was set, but @figure was used!")
616 #raise Exception("No backend was set, but @figure was used!")
617 import matplotlib
617 import matplotlib
618 matplotlib.use('agg')
618 matplotlib.use('agg')
619
619
620 # Always import pyplot into embedded shell.
620 # Always import pyplot into embedded shell.
621 self.process_input_line('import matplotlib.pyplot as plt',
621 self.process_input_line('import matplotlib.pyplot as plt',
622 store_history=False)
622 store_history=False)
623 self._pyplot_imported = True
623 self._pyplot_imported = True
624
624
625 def process_pure_python(self, content):
625 def process_pure_python(self, content):
626 """
626 """
627 content is a list of strings. it is unedited directive content
627 content is a list of strings. it is unedited directive content
628
628
629 This runs it line by line in the InteractiveShell, prepends
629 This runs it line by line in the InteractiveShell, prepends
630 prompts as needed capturing stderr and stdout, then returns
630 prompts as needed capturing stderr and stdout, then returns
631 the content as a list as if it were ipython code
631 the content as a list as if it were ipython code
632 """
632 """
633 output = []
633 output = []
634 savefig = False # keep up with this to clear figure
634 savefig = False # keep up with this to clear figure
635 multiline = False # to handle line continuation
635 multiline = False # to handle line continuation
636 multiline_start = None
636 multiline_start = None
637 fmtin = self.promptin
637 fmtin = self.promptin
638
638
639 ct = 0
639 ct = 0
640
640
641 for lineno, line in enumerate(content):
641 for lineno, line in enumerate(content):
642
642
643 line_stripped = line.strip()
643 line_stripped = line.strip()
644 if not len(line):
644 if not len(line):
645 output.append(line)
645 output.append(line)
646 continue
646 continue
647
647
648 # handle decorators
648 # handle decorators
649 if line_stripped.startswith('@'):
649 if line_stripped.startswith('@'):
650 output.extend([line])
650 output.extend([line])
651 if 'savefig' in line:
651 if 'savefig' in line:
652 savefig = True # and need to clear figure
652 savefig = True # and need to clear figure
653 continue
653 continue
654
654
655 # handle comments
655 # handle comments
656 if line_stripped.startswith('#'):
656 if line_stripped.startswith('#'):
657 output.extend([line])
657 output.extend([line])
658 continue
658 continue
659
659
660 # deal with lines checking for multiline
660 # deal with lines checking for multiline
661 continuation = u' %s:'% ''.join(['.']*(len(str(ct))+2))
661 continuation = u' %s:'% ''.join(['.']*(len(str(ct))+2))
662 if not multiline:
662 if not multiline:
663 modified = u"%s %s" % (fmtin % ct, line_stripped)
663 modified = u"%s %s" % (fmtin % ct, line_stripped)
664 output.append(modified)
664 output.append(modified)
665 ct += 1
665 ct += 1
666 try:
666 try:
667 ast.parse(line_stripped)
667 ast.parse(line_stripped)
668 output.append(u'')
668 output.append(u'')
669 except Exception: # on a multiline
669 except Exception: # on a multiline
670 multiline = True
670 multiline = True
671 multiline_start = lineno
671 multiline_start = lineno
672 else: # still on a multiline
672 else: # still on a multiline
673 modified = u'%s %s' % (continuation, line)
673 modified = u'%s %s' % (continuation, line)
674 output.append(modified)
674 output.append(modified)
675
675
676 # if the next line is indented, it should be part of multiline
676 # if the next line is indented, it should be part of multiline
677 if len(content) > lineno + 1:
677 if len(content) > lineno + 1:
678 nextline = content[lineno + 1]
678 nextline = content[lineno + 1]
679 if len(nextline) - len(nextline.lstrip()) > 3:
679 if len(nextline) - len(nextline.lstrip()) > 3:
680 continue
680 continue
681 try:
681 try:
682 mod = ast.parse(
682 mod = ast.parse(
683 '\n'.join(content[multiline_start:lineno+1]))
683 '\n'.join(content[multiline_start:lineno+1]))
684 if isinstance(mod.body[0], ast.FunctionDef):
684 if isinstance(mod.body[0], ast.FunctionDef):
685 # check to see if we have the whole function
685 # check to see if we have the whole function
686 for element in mod.body[0].body:
686 for element in mod.body[0].body:
687 if isinstance(element, ast.Return):
687 if isinstance(element, ast.Return):
688 multiline = False
688 multiline = False
689 else:
689 else:
690 output.append(u'')
690 output.append(u'')
691 multiline = False
691 multiline = False
692 except Exception:
692 except Exception:
693 pass
693 pass
694
694
695 if savefig: # clear figure if plotted
695 if savefig: # clear figure if plotted
696 self.ensure_pyplot()
696 self.ensure_pyplot()
697 self.process_input_line('plt.clf()', store_history=False)
697 self.process_input_line('plt.clf()', store_history=False)
698 self.clear_cout()
698 self.clear_cout()
699 savefig = False
699 savefig = False
700
700
701 return output
701 return output
702
702
703 def custom_doctest(self, decorator, input_lines, found, submitted):
703 def custom_doctest(self, decorator, input_lines, found, submitted):
704 """
704 """
705 Perform a specialized doctest.
705 Perform a specialized doctest.
706
706
707 """
707 """
708 from .custom_doctests import doctests
708 from .custom_doctests import doctests
709
709
710 args = decorator.split()
710 args = decorator.split()
711 doctest_type = args[1]
711 doctest_type = args[1]
712 if doctest_type in doctests:
712 if doctest_type in doctests:
713 doctests[doctest_type](self, args, input_lines, found, submitted)
713 doctests[doctest_type](self, args, input_lines, found, submitted)
714 else:
714 else:
715 e = "Invalid option to @doctest: {0}".format(doctest_type)
715 e = "Invalid option to @doctest: {0}".format(doctest_type)
716 raise Exception(e)
716 raise Exception(e)
717
717
718
718
719 class IPythonDirective(Directive):
719 class IPythonDirective(Directive):
720
720
721 has_content = True
721 has_content = True
722 required_arguments = 0
722 required_arguments = 0
723 optional_arguments = 4 # python, suppress, verbatim, doctest
723 optional_arguments = 4 # python, suppress, verbatim, doctest
724 final_argumuent_whitespace = True
724 final_argumuent_whitespace = True
725 option_spec = { 'python': directives.unchanged,
725 option_spec = { 'python': directives.unchanged,
726 'suppress' : directives.flag,
726 'suppress' : directives.flag,
727 'verbatim' : directives.flag,
727 'verbatim' : directives.flag,
728 'doctest' : directives.flag,
728 'doctest' : directives.flag,
729 'okexcept': directives.flag,
729 'okexcept': directives.flag,
730 'okwarning': directives.flag
730 'okwarning': directives.flag
731 }
731 }
732
732
733 shell = None
733 shell = None
734
734
735 seen_docs = set()
735 seen_docs = set()
736
736
737 def get_config_options(self):
737 def get_config_options(self):
738 # contains sphinx configuration variables
738 # contains sphinx configuration variables
739 config = self.state.document.settings.env.config
739 config = self.state.document.settings.env.config
740
740
741 # get config variables to set figure output directory
741 # get config variables to set figure output directory
742 confdir = self.state.document.settings.env.app.confdir
742 confdir = self.state.document.settings.env.app.confdir
743 savefig_dir = config.ipython_savefig_dir
743 savefig_dir = config.ipython_savefig_dir
744 source_dir = os.path.dirname(self.state.document.current_source)
744 source_dir = os.path.dirname(self.state.document.current_source)
745 if savefig_dir is None:
745 if savefig_dir is None:
746 savefig_dir = config.html_static_path
746 savefig_dir = config.html_static_path
747 if isinstance(savefig_dir, list):
747 if isinstance(savefig_dir, list):
748 savefig_dir = savefig_dir[0] # safe to assume only one path?
748 savefig_dir = savefig_dir[0] # safe to assume only one path?
749 savefig_dir = os.path.join(confdir, savefig_dir)
749 savefig_dir = os.path.join(confdir, savefig_dir)
750
750
751 # get regex and prompt stuff
751 # get regex and prompt stuff
752 rgxin = config.ipython_rgxin
752 rgxin = config.ipython_rgxin
753 rgxout = config.ipython_rgxout
753 rgxout = config.ipython_rgxout
754 promptin = config.ipython_promptin
754 promptin = config.ipython_promptin
755 promptout = config.ipython_promptout
755 promptout = config.ipython_promptout
756 mplbackend = config.ipython_mplbackend
756 mplbackend = config.ipython_mplbackend
757 exec_lines = config.ipython_execlines
757 exec_lines = config.ipython_execlines
758 hold_count = config.ipython_holdcount
758 hold_count = config.ipython_holdcount
759
759
760 return (savefig_dir, source_dir, rgxin, rgxout,
760 return (savefig_dir, source_dir, rgxin, rgxout,
761 promptin, promptout, mplbackend, exec_lines, hold_count)
761 promptin, promptout, mplbackend, exec_lines, hold_count)
762
762
763 def setup(self):
763 def setup(self):
764 # Get configuration values.
764 # Get configuration values.
765 (savefig_dir, source_dir, rgxin, rgxout, promptin, promptout,
765 (savefig_dir, source_dir, rgxin, rgxout, promptin, promptout,
766 mplbackend, exec_lines, hold_count) = self.get_config_options()
766 mplbackend, exec_lines, hold_count) = self.get_config_options()
767
767
768 if self.shell is None:
768 if self.shell is None:
769 # We will be here many times. However, when the
769 # We will be here many times. However, when the
770 # EmbeddedSphinxShell is created, its interactive shell member
770 # EmbeddedSphinxShell is created, its interactive shell member
771 # is the same for each instance.
771 # is the same for each instance.
772
772
773 if mplbackend:
773 if mplbackend:
774 import matplotlib
774 import matplotlib
775 # Repeated calls to use() will not hurt us since `mplbackend`
775 # Repeated calls to use() will not hurt us since `mplbackend`
776 # is the same each time.
776 # is the same each time.
777 matplotlib.use(mplbackend)
777 matplotlib.use(mplbackend)
778
778
779 # Must be called after (potentially) importing matplotlib and
779 # Must be called after (potentially) importing matplotlib and
780 # setting its backend since exec_lines might import pylab.
780 # setting its backend since exec_lines might import pylab.
781 self.shell = EmbeddedSphinxShell(exec_lines)
781 self.shell = EmbeddedSphinxShell(exec_lines)
782
782
783 # Store IPython directive to enable better error messages
783 # Store IPython directive to enable better error messages
784 self.shell.directive = self
784 self.shell.directive = self
785
785
786 # reset the execution count if we haven't processed this doc
786 # reset the execution count if we haven't processed this doc
787 #NOTE: this may be borked if there are multiple seen_doc tmp files
787 #NOTE: this may be borked if there are multiple seen_doc tmp files
788 #check time stamp?
788 #check time stamp?
789 if not self.state.document.current_source in self.seen_docs:
789 if not self.state.document.current_source in self.seen_docs:
790 self.shell.IP.history_manager.reset()
790 self.shell.IP.history_manager.reset()
791 self.shell.IP.execution_count = 1
791 self.shell.IP.execution_count = 1
792 self.shell.IP.prompt_manager.width = 0
792 self.shell.IP.prompt_manager.width = 0
793 self.seen_docs.add(self.state.document.current_source)
793 self.seen_docs.add(self.state.document.current_source)
794
794
795 # and attach to shell so we don't have to pass them around
795 # and attach to shell so we don't have to pass them around
796 self.shell.rgxin = rgxin
796 self.shell.rgxin = rgxin
797 self.shell.rgxout = rgxout
797 self.shell.rgxout = rgxout
798 self.shell.promptin = promptin
798 self.shell.promptin = promptin
799 self.shell.promptout = promptout
799 self.shell.promptout = promptout
800 self.shell.savefig_dir = savefig_dir
800 self.shell.savefig_dir = savefig_dir
801 self.shell.source_dir = source_dir
801 self.shell.source_dir = source_dir
802 self.shell.hold_count = hold_count
802 self.shell.hold_count = hold_count
803
803
804 # setup bookmark for saving figures directory
804 # setup bookmark for saving figures directory
805 self.shell.process_input_line('bookmark ipy_savedir %s'%savefig_dir,
805 self.shell.process_input_line('bookmark ipy_savedir %s'%savefig_dir,
806 store_history=False)
806 store_history=False)
807 self.shell.clear_cout()
807 self.shell.clear_cout()
808
808
809 return rgxin, rgxout, promptin, promptout
809 return rgxin, rgxout, promptin, promptout
810
810
811 def teardown(self):
811 def teardown(self):
812 # delete last bookmark
812 # delete last bookmark
813 self.shell.process_input_line('bookmark -d ipy_savedir',
813 self.shell.process_input_line('bookmark -d ipy_savedir',
814 store_history=False)
814 store_history=False)
815 self.shell.clear_cout()
815 self.shell.clear_cout()
816
816
817 def run(self):
817 def run(self):
818 debug = False
818 debug = False
819
819
820 #TODO, any reason block_parser can't be a method of embeddable shell
820 #TODO, any reason block_parser can't be a method of embeddable shell
821 # then we wouldn't have to carry these around
821 # then we wouldn't have to carry these around
822 rgxin, rgxout, promptin, promptout = self.setup()
822 rgxin, rgxout, promptin, promptout = self.setup()
823
823
824 options = self.options
824 options = self.options
825 self.shell.is_suppress = 'suppress' in options
825 self.shell.is_suppress = 'suppress' in options
826 self.shell.is_doctest = 'doctest' in options
826 self.shell.is_doctest = 'doctest' in options
827 self.shell.is_verbatim = 'verbatim' in options
827 self.shell.is_verbatim = 'verbatim' in options
828 self.shell.is_okexcept = 'okexcept' in options
828 self.shell.is_okexcept = 'okexcept' in options
829 self.shell.is_okwarning = 'okwarning' in options
829 self.shell.is_okwarning = 'okwarning' in options
830
830
831 # handle pure python code
831 # handle pure python code
832 if 'python' in self.arguments:
832 if 'python' in self.arguments:
833 content = self.content
833 content = self.content
834 self.content = self.shell.process_pure_python(content)
834 self.content = self.shell.process_pure_python(content)
835
835
836 parts = '\n'.join(self.content).split('\n\n')
836 parts = '\n'.join(self.content).split('\n\n')
837
837
838 lines = ['.. code-block:: ipython', '']
838 lines = ['.. code-block:: ipython', '']
839 figures = []
839 figures = []
840
840
841 for part in parts:
841 for part in parts:
842 block = block_parser(part, rgxin, rgxout, promptin, promptout)
842 block = block_parser(part, rgxin, rgxout, promptin, promptout)
843 if len(block):
843 if len(block):
844 rows, figure = self.shell.process_block(block)
844 rows, figure = self.shell.process_block(block)
845 for row in rows:
845 for row in rows:
846 lines.extend([' %s'%line for line in row.split('\n')])
846 lines.extend([' %s'%line for line in row.split('\n')])
847
847
848 if figure is not None:
848 if figure is not None:
849 figures.append(figure)
849 figures.append(figure)
850
850
851 for figure in figures:
851 for figure in figures:
852 lines.append('')
852 lines.append('')
853 lines.extend(figure.split('\n'))
853 lines.extend(figure.split('\n'))
854 lines.append('')
854 lines.append('')
855
855
856 if len(lines)>2:
856 if len(lines)>2:
857 if debug:
857 if debug:
858 print('\n'.join(lines))
858 print('\n'.join(lines))
859 else:
859 else:
860 # This has to do with input, not output. But if we comment
860 # This has to do with input, not output. But if we comment
861 # these lines out, then no IPython code will appear in the
861 # these lines out, then no IPython code will appear in the
862 # final output.
862 # final output.
863 self.state_machine.insert_input(
863 self.state_machine.insert_input(
864 lines, self.state_machine.input_lines.source(0))
864 lines, self.state_machine.input_lines.source(0))
865
865
866 # cleanup
866 # cleanup
867 self.teardown()
867 self.teardown()
868
868
869 return []
869 return []
870
870
871 # Enable as a proper Sphinx directive
871 # Enable as a proper Sphinx directive
872 def setup(app):
872 def setup(app):
873 setup.app = app
873 setup.app = app
874
874
875 app.add_directive('ipython', IPythonDirective)
875 app.add_directive('ipython', IPythonDirective)
876 app.add_config_value('ipython_savefig_dir', None, 'env')
876 app.add_config_value('ipython_savefig_dir', None, 'env')
877 app.add_config_value('ipython_rgxin',
877 app.add_config_value('ipython_rgxin',
878 re.compile('In \[(\d+)\]:\s?(.*)\s*'), 'env')
878 re.compile('In \[(\d+)\]:\s?(.*)\s*'), 'env')
879 app.add_config_value('ipython_rgxout',
879 app.add_config_value('ipython_rgxout',
880 re.compile('Out\[(\d+)\]:\s?(.*)\s*'), 'env')
880 re.compile('Out\[(\d+)\]:\s?(.*)\s*'), 'env')
881 app.add_config_value('ipython_promptin', 'In [%d]:', 'env')
881 app.add_config_value('ipython_promptin', 'In [%d]:', 'env')
882 app.add_config_value('ipython_promptout', 'Out[%d]:', 'env')
882 app.add_config_value('ipython_promptout', 'Out[%d]:', 'env')
883
883
884 # We could just let matplotlib pick whatever is specified as the default
884 # We could just let matplotlib pick whatever is specified as the default
885 # backend in the matplotlibrc file, but this would cause issues if the
885 # backend in the matplotlibrc file, but this would cause issues if the
886 # backend didn't work in headless environments. For this reason, 'agg'
886 # backend didn't work in headless environments. For this reason, 'agg'
887 # is a good default backend choice.
887 # is a good default backend choice.
888 app.add_config_value('ipython_mplbackend', 'agg', 'env')
888 app.add_config_value('ipython_mplbackend', 'agg', 'env')
889
889
890 # If the user sets this config value to `None`, then EmbeddedSphinxShell's
890 # If the user sets this config value to `None`, then EmbeddedSphinxShell's
891 # __init__ method will treat it as [].
891 # __init__ method will treat it as [].
892 execlines = ['import numpy as np', 'import matplotlib.pyplot as plt']
892 execlines = ['import numpy as np', 'import matplotlib.pyplot as plt']
893 app.add_config_value('ipython_execlines', execlines, 'env')
893 app.add_config_value('ipython_execlines', execlines, 'env')
894
894
895 app.add_config_value('ipython_holdcount', True, 'env')
895 app.add_config_value('ipython_holdcount', True, 'env')
896
896
897 # Simple smoke test, needs to be converted to a proper automatic test.
897 # Simple smoke test, needs to be converted to a proper automatic test.
898 def test():
898 def test():
899
899
900 examples = [
900 examples = [
901 r"""
901 r"""
902 In [9]: pwd
902 In [9]: pwd
903 Out[9]: '/home/jdhunter/py4science/book'
903 Out[9]: '/home/jdhunter/py4science/book'
904
904
905 In [10]: cd bookdata/
905 In [10]: cd bookdata/
906 /home/jdhunter/py4science/book/bookdata
906 /home/jdhunter/py4science/book/bookdata
907
907
908 In [2]: from pylab import *
908 In [2]: from pylab import *
909
909
910 In [2]: ion()
910 In [2]: ion()
911
911
912 In [3]: im = imread('stinkbug.png')
912 In [3]: im = imread('stinkbug.png')
913
913
914 @savefig mystinkbug.png width=4in
914 @savefig mystinkbug.png width=4in
915 In [4]: imshow(im)
915 In [4]: imshow(im)
916 Out[4]: <matplotlib.image.AxesImage object at 0x39ea850>
916 Out[4]: <matplotlib.image.AxesImage object at 0x39ea850>
917
917
918 """,
918 """,
919 r"""
919 r"""
920
920
921 In [1]: x = 'hello world'
921 In [1]: x = 'hello world'
922
922
923 # string methods can be
923 # string methods can be
924 # used to alter the string
924 # used to alter the string
925 @doctest
925 @doctest
926 In [2]: x.upper()
926 In [2]: x.upper()
927 Out[2]: 'HELLO WORLD'
927 Out[2]: 'HELLO WORLD'
928
928
929 @verbatim
929 @verbatim
930 In [3]: x.st<TAB>
930 In [3]: x.st<TAB>
931 x.startswith x.strip
931 x.startswith x.strip
932 """,
932 """,
933 r"""
933 r"""
934
934
935 In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\
935 In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\
936 .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv'
936 .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv'
937
937
938 In [131]: print url.split('&')
938 In [131]: print url.split('&')
939 ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv']
939 ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv']
940
940
941 In [60]: import urllib
941 In [60]: import urllib
942
942
943 """,
943 """,
944 r"""\
944 r"""\
945
945
946 In [133]: import numpy.random
946 In [133]: import numpy.random
947
947
948 @suppress
948 @suppress
949 In [134]: numpy.random.seed(2358)
949 In [134]: numpy.random.seed(2358)
950
950
951 @doctest
951 @doctest
952 In [135]: numpy.random.rand(10,2)
952 In [135]: numpy.random.rand(10,2)
953 Out[135]:
953 Out[135]:
954 array([[ 0.64524308, 0.59943846],
954 array([[ 0.64524308, 0.59943846],
955 [ 0.47102322, 0.8715456 ],
955 [ 0.47102322, 0.8715456 ],
956 [ 0.29370834, 0.74776844],
956 [ 0.29370834, 0.74776844],
957 [ 0.99539577, 0.1313423 ],
957 [ 0.99539577, 0.1313423 ],
958 [ 0.16250302, 0.21103583],
958 [ 0.16250302, 0.21103583],
959 [ 0.81626524, 0.1312433 ],
959 [ 0.81626524, 0.1312433 ],
960 [ 0.67338089, 0.72302393],
960 [ 0.67338089, 0.72302393],
961 [ 0.7566368 , 0.07033696],
961 [ 0.7566368 , 0.07033696],
962 [ 0.22591016, 0.77731835],
962 [ 0.22591016, 0.77731835],
963 [ 0.0072729 , 0.34273127]])
963 [ 0.0072729 , 0.34273127]])
964
964
965 """,
965 """,
966
966
967 r"""
967 r"""
968 In [106]: print x
968 In [106]: print x
969 jdh
969 jdh
970
970
971 In [109]: for i in range(10):
971 In [109]: for i in range(10):
972 .....: print i
972 .....: print i
973 .....:
973 .....:
974 .....:
974 .....:
975 0
975 0
976 1
976 1
977 2
977 2
978 3
978 3
979 4
979 4
980 5
980 5
981 6
981 6
982 7
982 7
983 8
983 8
984 9
984 9
985 """,
985 """,
986
986
987 r"""
987 r"""
988
988
989 In [144]: from pylab import *
989 In [144]: from pylab import *
990
990
991 In [145]: ion()
991 In [145]: ion()
992
992
993 # use a semicolon to suppress the output
993 # use a semicolon to suppress the output
994 @savefig test_hist.png width=4in
994 @savefig test_hist.png width=4in
995 In [151]: hist(np.random.randn(10000), 100);
995 In [151]: hist(np.random.randn(10000), 100);
996
996
997
997
998 @savefig test_plot.png width=4in
998 @savefig test_plot.png width=4in
999 In [151]: plot(np.random.randn(10000), 'o');
999 In [151]: plot(np.random.randn(10000), 'o');
1000 """,
1000 """,
1001
1001
1002 r"""
1002 r"""
1003 # use a semicolon to suppress the output
1003 # use a semicolon to suppress the output
1004 In [151]: plt.clf()
1004 In [151]: plt.clf()
1005
1005
1006 @savefig plot_simple.png width=4in
1006 @savefig plot_simple.png width=4in
1007 In [151]: plot([1,2,3])
1007 In [151]: plot([1,2,3])
1008
1008
1009 @savefig hist_simple.png width=4in
1009 @savefig hist_simple.png width=4in
1010 In [151]: hist(np.random.randn(10000), 100);
1010 In [151]: hist(np.random.randn(10000), 100);
1011
1011
1012 """,
1012 """,
1013 r"""
1013 r"""
1014 # update the current fig
1014 # update the current fig
1015 In [151]: ylabel('number')
1015 In [151]: ylabel('number')
1016
1016
1017 In [152]: title('normal distribution')
1017 In [152]: title('normal distribution')
1018
1018
1019
1019
1020 @savefig hist_with_text.png
1020 @savefig hist_with_text.png
1021 In [153]: grid(True)
1021 In [153]: grid(True)
1022
1022
1023 @doctest float
1023 @doctest float
1024 In [154]: 0.1 + 0.2
1024 In [154]: 0.1 + 0.2
1025 Out[154]: 0.3
1025 Out[154]: 0.3
1026
1026
1027 @doctest float
1027 @doctest float
1028 In [155]: np.arange(16).reshape(4,4)
1028 In [155]: np.arange(16).reshape(4,4)
1029 Out[155]:
1029 Out[155]:
1030 array([[ 0, 1, 2, 3],
1030 array([[ 0, 1, 2, 3],
1031 [ 4, 5, 6, 7],
1031 [ 4, 5, 6, 7],
1032 [ 8, 9, 10, 11],
1032 [ 8, 9, 10, 11],
1033 [12, 13, 14, 15]])
1033 [12, 13, 14, 15]])
1034
1034
1035 In [1]: x = np.arange(16, dtype=float).reshape(4,4)
1035 In [1]: x = np.arange(16, dtype=float).reshape(4,4)
1036
1036
1037 In [2]: x[0,0] = np.inf
1037 In [2]: x[0,0] = np.inf
1038
1038
1039 In [3]: x[0,1] = np.nan
1039 In [3]: x[0,1] = np.nan
1040
1040
1041 @doctest float
1041 @doctest float
1042 In [4]: x
1042 In [4]: x
1043 Out[4]:
1043 Out[4]:
1044 array([[ inf, nan, 2., 3.],
1044 array([[ inf, nan, 2., 3.],
1045 [ 4., 5., 6., 7.],
1045 [ 4., 5., 6., 7.],
1046 [ 8., 9., 10., 11.],
1046 [ 8., 9., 10., 11.],
1047 [ 12., 13., 14., 15.]])
1047 [ 12., 13., 14., 15.]])
1048
1048
1049
1049
1050 """,
1050 """,
1051 ]
1051 ]
1052 # skip local-file depending first example:
1052 # skip local-file depending first example:
1053 examples = examples[1:]
1053 examples = examples[1:]
1054
1054
1055 #ipython_directive.DEBUG = True # dbg
1055 #ipython_directive.DEBUG = True # dbg
1056 #options = dict(suppress=True) # dbg
1056 #options = dict(suppress=True) # dbg
1057 options = dict()
1057 options = dict()
1058 for example in examples:
1058 for example in examples:
1059 content = example.split('\n')
1059 content = example.split('\n')
1060 IPythonDirective('debug', arguments=None, options=options,
1060 IPythonDirective('debug', arguments=None, options=options,
1061 content=content, lineno=0,
1061 content=content, lineno=0,
1062 content_offset=None, block_text=None,
1062 content_offset=None, block_text=None,
1063 state=None, state_machine=None,
1063 state=None, state_machine=None,
1064 )
1064 )
1065
1065
1066 # Run test suite as a script
1066 # Run test suite as a script
1067 if __name__=='__main__':
1067 if __name__=='__main__':
1068 if not os.path.isdir('_static'):
1068 if not os.path.isdir('_static'):
1069 os.mkdir('_static')
1069 os.mkdir('_static')
1070 test()
1070 test()
1071 print('All OK? Check figures in _static/')
1071 print('All OK? Check figures in _static/')
@@ -1,501 +1,506 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """terminal client to the IPython kernel
2 """terminal client to the IPython kernel
3
3
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2013 The IPython Development Team
6 # Copyright (C) 2013 The IPython Development Team
7 #
7 #
8 # Distributed under the terms of the BSD License. The full license is in
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING, distributed as part of this software.
9 # the file COPYING, distributed as part of this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from __future__ import print_function
15 from __future__ import print_function
16
16
17 import bdb
17 import bdb
18 import signal
18 import signal
19 import os
19 import os
20 import sys
20 import sys
21 import time
21 import time
22 import subprocess
22 import subprocess
23 from io import BytesIO
23 from io import BytesIO
24 import base64
24 import base64
25
25
26 try:
26 try:
27 from queue import Empty # Py 3
27 from queue import Empty # Py 3
28 except ImportError:
28 except ImportError:
29 from Queue import Empty # Py 2
29 from Queue import Empty # Py 2
30
30
31 from IPython.core import page
31 from IPython.core import page
32 from IPython.utils.warn import warn, error
32 from IPython.utils.warn import warn, error
33 from IPython.utils import io
33 from IPython.utils import io
34 from IPython.utils.py3compat import string_types, input
34 from IPython.utils.py3compat import string_types, input
35 from IPython.utils.traitlets import List, Enum, Any, Instance, Unicode, Float
35 from IPython.utils.traitlets import List, Enum, Any, Instance, Unicode, Float
36 from IPython.utils.tempdir import NamedFileInTemporaryDirectory
36 from IPython.utils.tempdir import NamedFileInTemporaryDirectory
37
37
38 from IPython.terminal.interactiveshell import TerminalInteractiveShell
38 from IPython.terminal.interactiveshell import TerminalInteractiveShell
39 from IPython.terminal.console.completer import ZMQCompleter
39 from IPython.terminal.console.completer import ZMQCompleter
40
40
41
41
42 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
42 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
43 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
43 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
44 _executing = False
44 _executing = False
45 _execution_state = Unicode('')
45 _execution_state = Unicode('')
46 kernel_timeout = Float(60, config=True,
46 kernel_timeout = Float(60, config=True,
47 help="""Timeout for giving up on a kernel (in seconds).
47 help="""Timeout for giving up on a kernel (in seconds).
48
48
49 On first connect and restart, the console tests whether the
49 On first connect and restart, the console tests whether the
50 kernel is running and responsive by sending kernel_info_requests.
50 kernel is running and responsive by sending kernel_info_requests.
51 This sets the timeout in seconds for how long the kernel can take
51 This sets the timeout in seconds for how long the kernel can take
52 before being presumed dead.
52 before being presumed dead.
53 """
53 """
54 )
54 )
55
55
56 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
56 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
57 config=True, help=
57 config=True, help=
58 """
58 """
59 Handler for image type output. This is useful, for example,
59 Handler for image type output. This is useful, for example,
60 when connecting to the kernel in which pylab inline backend is
60 when connecting to the kernel in which pylab inline backend is
61 activated. There are four handlers defined. 'PIL': Use
61 activated. There are four handlers defined. 'PIL': Use
62 Python Imaging Library to popup image; 'stream': Use an
62 Python Imaging Library to popup image; 'stream': Use an
63 external program to show the image. Image will be fed into
63 external program to show the image. Image will be fed into
64 the STDIN of the program. You will need to configure
64 the STDIN of the program. You will need to configure
65 `stream_image_handler`; 'tempfile': Use an external program to
65 `stream_image_handler`; 'tempfile': Use an external program to
66 show the image. Image will be saved in a temporally file and
66 show the image. Image will be saved in a temporally file and
67 the program is called with the temporally file. You will need
67 the program is called with the temporally file. You will need
68 to configure `tempfile_image_handler`; 'callable': You can set
68 to configure `tempfile_image_handler`; 'callable': You can set
69 any Python callable which is called with the image data. You
69 any Python callable which is called with the image data. You
70 will need to configure `callable_image_handler`.
70 will need to configure `callable_image_handler`.
71 """
71 """
72 )
72 )
73
73
74 stream_image_handler = List(config=True, help=
74 stream_image_handler = List(config=True, help=
75 """
75 """
76 Command to invoke an image viewer program when you are using
76 Command to invoke an image viewer program when you are using
77 'stream' image handler. This option is a list of string where
77 'stream' image handler. This option is a list of string where
78 the first element is the command itself and reminders are the
78 the first element is the command itself and reminders are the
79 options for the command. Raw image data is given as STDIN to
79 options for the command. Raw image data is given as STDIN to
80 the program.
80 the program.
81 """
81 """
82 )
82 )
83
83
84 tempfile_image_handler = List(config=True, help=
84 tempfile_image_handler = List(config=True, help=
85 """
85 """
86 Command to invoke an image viewer program when you are using
86 Command to invoke an image viewer program when you are using
87 'tempfile' image handler. This option is a list of string
87 'tempfile' image handler. This option is a list of string
88 where the first element is the command itself and reminders
88 where the first element is the command itself and reminders
89 are the options for the command. You can use {file} and
89 are the options for the command. You can use {file} and
90 {format} in the string to represent the location of the
90 {format} in the string to represent the location of the
91 generated image file and image format.
91 generated image file and image format.
92 """
92 """
93 )
93 )
94
94
95 callable_image_handler = Any(config=True, help=
95 callable_image_handler = Any(config=True, help=
96 """
96 """
97 Callable object called via 'callable' image handler with one
97 Callable object called via 'callable' image handler with one
98 argument, `data`, which is `msg["content"]["data"]` where
98 argument, `data`, which is `msg["content"]["data"]` where
99 `msg` is the message from iopub channel. For exmaple, you can
99 `msg` is the message from iopub channel. For exmaple, you can
100 find base64 encoded PNG data as `data['image/png']`.
100 find base64 encoded PNG data as `data['image/png']`.
101 """
101 """
102 )
102 )
103
103
104 mime_preference = List(
104 mime_preference = List(
105 default_value=['image/png', 'image/jpeg', 'image/svg+xml'],
105 default_value=['image/png', 'image/jpeg', 'image/svg+xml'],
106 config=True, allow_none=False, help=
106 config=True, allow_none=False, help=
107 """
107 """
108 Preferred object representation MIME type in order. First
108 Preferred object representation MIME type in order. First
109 matched MIME type will be used.
109 matched MIME type will be used.
110 """
110 """
111 )
111 )
112
112
113 manager = Instance('IPython.kernel.KernelManager')
113 manager = Instance('IPython.kernel.KernelManager')
114 client = Instance('IPython.kernel.KernelClient')
114 client = Instance('IPython.kernel.KernelClient')
115 def _client_changed(self, name, old, new):
115 def _client_changed(self, name, old, new):
116 self.session_id = new.session.session
116 self.session_id = new.session.session
117 session_id = Unicode()
117 session_id = Unicode()
118
118
119 def init_completer(self):
119 def init_completer(self):
120 """Initialize the completion machinery.
120 """Initialize the completion machinery.
121
121
122 This creates completion machinery that can be used by client code,
122 This creates completion machinery that can be used by client code,
123 either interactively in-process (typically triggered by the readline
123 either interactively in-process (typically triggered by the readline
124 library), programmatically (such as in test suites) or out-of-process
124 library), programmatically (such as in test suites) or out-of-process
125 (typically over the network by remote frontends).
125 (typically over the network by remote frontends).
126 """
126 """
127 from IPython.core.completerlib import (module_completer,
127 from IPython.core.completerlib import (module_completer,
128 magic_run_completer, cd_completer)
128 magic_run_completer, cd_completer)
129
129
130 self.Completer = ZMQCompleter(self, self.client, config=self.config)
130 self.Completer = ZMQCompleter(self, self.client, config=self.config)
131
131
132
132
133 self.set_hook('complete_command', module_completer, str_key = 'import')
133 self.set_hook('complete_command', module_completer, str_key = 'import')
134 self.set_hook('complete_command', module_completer, str_key = 'from')
134 self.set_hook('complete_command', module_completer, str_key = 'from')
135 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
135 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
136 self.set_hook('complete_command', cd_completer, str_key = '%cd')
136 self.set_hook('complete_command', cd_completer, str_key = '%cd')
137
137
138 # Only configure readline if we truly are using readline. IPython can
138 # Only configure readline if we truly are using readline. IPython can
139 # do tab-completion over the network, in GUIs, etc, where readline
139 # do tab-completion over the network, in GUIs, etc, where readline
140 # itself may be absent
140 # itself may be absent
141 if self.has_readline:
141 if self.has_readline:
142 self.set_readline_completer()
142 self.set_readline_completer()
143
143
144 def ask_exit(self):
144 def ask_exit(self):
145 super(ZMQTerminalInteractiveShell, self).ask_exit()
145 super(ZMQTerminalInteractiveShell, self).ask_exit()
146 if self.exit_now and self.manager:
146 if self.exit_now and self.manager:
147 self.client.shutdown()
147 self.client.shutdown()
148
148
149 def run_cell(self, cell, store_history=True):
149 def run_cell(self, cell, store_history=True):
150 """Run a complete IPython cell.
150 """Run a complete IPython cell.
151
151
152 Parameters
152 Parameters
153 ----------
153 ----------
154 cell : str
154 cell : str
155 The code (including IPython code such as %magic functions) to run.
155 The code (including IPython code such as %magic functions) to run.
156 store_history : bool
156 store_history : bool
157 If True, the raw and translated cell will be stored in IPython's
157 If True, the raw and translated cell will be stored in IPython's
158 history. For user code calling back into IPython's machinery, this
158 history. For user code calling back into IPython's machinery, this
159 should be set to False.
159 should be set to False.
160 """
160 """
161 if (not cell) or cell.isspace():
161 if (not cell) or cell.isspace():
162 return
162 return
163
163
164 if cell.strip() == 'exit':
164 if cell.strip() == 'exit':
165 # explicitly handle 'exit' command
165 # explicitly handle 'exit' command
166 return self.ask_exit()
166 return self.ask_exit()
167
167
168 # flush stale replies, which could have been ignored, due to missed heartbeats
168 # flush stale replies, which could have been ignored, due to missed heartbeats
169 while self.client.shell_channel.msg_ready():
169 while self.client.shell_channel.msg_ready():
170 self.client.shell_channel.get_msg()
170 self.client.shell_channel.get_msg()
171 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
171 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
172 msg_id = self.client.shell_channel.execute(cell, not store_history)
172 msg_id = self.client.shell_channel.execute(cell, not store_history)
173
173
174 # first thing is wait for any side effects (output, stdin, etc.)
174 # first thing is wait for any side effects (output, stdin, etc.)
175 self._executing = True
175 self._executing = True
176 self._execution_state = "busy"
176 self._execution_state = "busy"
177 while self._execution_state != 'idle' and self.client.is_alive():
177 while self._execution_state != 'idle' and self.client.is_alive():
178 try:
178 try:
179 self.handle_stdin_request(msg_id, timeout=0.05)
179 self.handle_stdin_request(msg_id, timeout=0.05)
180 except Empty:
180 except Empty:
181 # display intermediate print statements, etc.
181 # display intermediate print statements, etc.
182 self.handle_iopub(msg_id)
182 self.handle_iopub(msg_id)
183 pass
183 pass
184
184
185 # after all of that is done, wait for the execute reply
185 # after all of that is done, wait for the execute reply
186 while self.client.is_alive():
186 while self.client.is_alive():
187 try:
187 try:
188 self.handle_execute_reply(msg_id, timeout=0.05)
188 self.handle_execute_reply(msg_id, timeout=0.05)
189 except Empty:
189 except Empty:
190 pass
190 pass
191 else:
191 else:
192 break
192 break
193 self._executing = False
193 self._executing = False
194
194
195 #-----------------
195 #-----------------
196 # message handlers
196 # message handlers
197 #-----------------
197 #-----------------
198
198
199 def handle_execute_reply(self, msg_id, timeout=None):
199 def handle_execute_reply(self, msg_id, timeout=None):
200 msg = self.client.shell_channel.get_msg(block=False, timeout=timeout)
200 msg = self.client.shell_channel.get_msg(block=False, timeout=timeout)
201 if msg["parent_header"].get("msg_id", None) == msg_id:
201 if msg["parent_header"].get("msg_id", None) == msg_id:
202
202
203 self.handle_iopub(msg_id)
203 self.handle_iopub(msg_id)
204
204
205 content = msg["content"]
205 content = msg["content"]
206 status = content['status']
206 status = content['status']
207
207
208 if status == 'aborted':
208 if status == 'aborted':
209 self.write('Aborted\n')
209 self.write('Aborted\n')
210 return
210 return
211 elif status == 'ok':
211 elif status == 'ok':
212 # print execution payloads as well:
212 # print execution payloads as well:
213 for item in content["payload"]:
213 for item in content["payload"]:
214 text = item.get('text', None)
214 text = item.get('text', None)
215 if text:
215 if text:
216 page.page(text)
216 page.page(text)
217
217
218 elif status == 'error':
218 elif status == 'error':
219 for frame in content["traceback"]:
219 for frame in content["traceback"]:
220 print(frame, file=io.stderr)
220 print(frame, file=io.stderr)
221
221
222 self.execution_count = int(content["execution_count"] + 1)
222 self.execution_count = int(content["execution_count"] + 1)
223
223
224
224
225 def handle_iopub(self, msg_id):
225 def handle_iopub(self, msg_id):
226 """ Method to process subscribe channel's messages
226 """ Method to process subscribe channel's messages
227
227
228 This method consumes and processes messages on the IOPub channel,
228 This method consumes and processes messages on the IOPub channel,
229 such as stdout, stderr, pyout and status.
229 such as stdout, stderr, pyout and status.
230
230
231 It only displays output that is caused by the given msg_id
231 It only displays output that is caused by the given msg_id
232 """
232 """
233 while self.client.iopub_channel.msg_ready():
233 while self.client.iopub_channel.msg_ready():
234 sub_msg = self.client.iopub_channel.get_msg()
234 sub_msg = self.client.iopub_channel.get_msg()
235 msg_type = sub_msg['header']['msg_type']
235 msg_type = sub_msg['header']['msg_type']
236 parent = sub_msg["parent_header"]
236 parent = sub_msg["parent_header"]
237 if (not parent) or msg_id == parent['msg_id']:
237 if (not parent) or msg_id == parent['msg_id']:
238 if msg_type == 'status':
238 if msg_type == 'status':
239 state = self._execution_state = sub_msg["content"]["execution_state"]
239 state = self._execution_state = sub_msg["content"]["execution_state"]
240 # idle messages mean an individual sequence is complete,
240 # idle messages mean an individual sequence is complete,
241 # so break out of consumption to allow other things to take over.
241 # so break out of consumption to allow other things to take over.
242 if state == 'idle':
242 if state == 'idle':
243 break
243 break
244
244
245 elif msg_type == 'stream':
245 elif msg_type == 'stream':
246 if sub_msg["content"]["name"] == "stdout":
246 if sub_msg["content"]["name"] == "stdout":
247 print(sub_msg["content"]["data"], file=io.stdout, end="")
247 print(sub_msg["content"]["data"], file=io.stdout, end="")
248 io.stdout.flush()
248 io.stdout.flush()
249 elif sub_msg["content"]["name"] == "stderr" :
249 elif sub_msg["content"]["name"] == "stderr" :
250 print(sub_msg["content"]["data"], file=io.stderr, end="")
250 print(sub_msg["content"]["data"], file=io.stderr, end="")
251 io.stderr.flush()
251 io.stderr.flush()
252
252
253 elif msg_type == 'pyout':
253 elif msg_type == 'pyout':
254 self.execution_count = int(sub_msg["content"]["execution_count"])
254 self.execution_count = int(sub_msg["content"]["execution_count"])
255 format_dict = sub_msg["content"]["data"]
255 format_dict = sub_msg["content"]["data"]
256 self.handle_rich_data(format_dict)
256 self.handle_rich_data(format_dict)
257 # taken from DisplayHook.__call__:
257 # taken from DisplayHook.__call__:
258 hook = self.displayhook
258 hook = self.displayhook
259 hook.start_displayhook()
259 hook.start_displayhook()
260 hook.write_output_prompt()
260 hook.write_output_prompt()
261 hook.write_format_data(format_dict)
261 hook.write_format_data(format_dict)
262 hook.log_output(format_dict)
262 hook.log_output(format_dict)
263 hook.finish_displayhook()
263 hook.finish_displayhook()
264
264
265 elif msg_type == 'display_data':
265 elif msg_type == 'display_data':
266 data = sub_msg["content"]["data"]
266 data = sub_msg["content"]["data"]
267 handled = self.handle_rich_data(data)
267 handled = self.handle_rich_data(data)
268 if not handled:
268 if not handled:
269 # if it was an image, we handled it by now
269 # if it was an image, we handled it by now
270 if 'text/plain' in data:
270 if 'text/plain' in data:
271 print(data['text/plain'])
271 print(data['text/plain'])
272
272
273 _imagemime = {
273 _imagemime = {
274 'image/png': 'png',
274 'image/png': 'png',
275 'image/jpeg': 'jpeg',
275 'image/jpeg': 'jpeg',
276 'image/svg+xml': 'svg',
276 'image/svg+xml': 'svg',
277 }
277 }
278
278
279 def handle_rich_data(self, data):
279 def handle_rich_data(self, data):
280 for mime in self.mime_preference:
280 for mime in self.mime_preference:
281 if mime in data and mime in self._imagemime:
281 if mime in data and mime in self._imagemime:
282 self.handle_image(data, mime)
282 self.handle_image(data, mime)
283 return True
283 return True
284
284
285 def handle_image(self, data, mime):
285 def handle_image(self, data, mime):
286 handler = getattr(
286 handler = getattr(
287 self, 'handle_image_{0}'.format(self.image_handler), None)
287 self, 'handle_image_{0}'.format(self.image_handler), None)
288 if handler:
288 if handler:
289 handler(data, mime)
289 handler(data, mime)
290
290
291 def handle_image_PIL(self, data, mime):
291 def handle_image_PIL(self, data, mime):
292 if mime not in ('image/png', 'image/jpeg'):
292 if mime not in ('image/png', 'image/jpeg'):
293 return
293 return
294 import PIL.Image
294 import PIL.Image
295 raw = base64.decodestring(data[mime].encode('ascii'))
295 raw = base64.decodestring(data[mime].encode('ascii'))
296 img = PIL.Image.open(BytesIO(raw))
296 img = PIL.Image.open(BytesIO(raw))
297 img.show()
297 img.show()
298
298
299 def handle_image_stream(self, data, mime):
299 def handle_image_stream(self, data, mime):
300 raw = base64.decodestring(data[mime].encode('ascii'))
300 raw = base64.decodestring(data[mime].encode('ascii'))
301 imageformat = self._imagemime[mime]
301 imageformat = self._imagemime[mime]
302 fmt = dict(format=imageformat)
302 fmt = dict(format=imageformat)
303 args = [s.format(**fmt) for s in self.stream_image_handler]
303 args = [s.format(**fmt) for s in self.stream_image_handler]
304 with open(os.devnull, 'w') as devnull:
304 with open(os.devnull, 'w') as devnull:
305 proc = subprocess.Popen(
305 proc = subprocess.Popen(
306 args, stdin=subprocess.PIPE,
306 args, stdin=subprocess.PIPE,
307 stdout=devnull, stderr=devnull)
307 stdout=devnull, stderr=devnull)
308 proc.communicate(raw)
308 proc.communicate(raw)
309
309
310 def handle_image_tempfile(self, data, mime):
310 def handle_image_tempfile(self, data, mime):
311 raw = base64.decodestring(data[mime].encode('ascii'))
311 raw = base64.decodestring(data[mime].encode('ascii'))
312 imageformat = self._imagemime[mime]
312 imageformat = self._imagemime[mime]
313 filename = 'tmp.{0}'.format(imageformat)
313 filename = 'tmp.{0}'.format(imageformat)
314 with NamedFileInTemporaryDirectory(filename) as f, \
314 with NamedFileInTemporaryDirectory(filename) as f, \
315 open(os.devnull, 'w') as devnull:
315 open(os.devnull, 'w') as devnull:
316 f.write(raw)
316 f.write(raw)
317 f.flush()
317 f.flush()
318 fmt = dict(file=f.name, format=imageformat)
318 fmt = dict(file=f.name, format=imageformat)
319 args = [s.format(**fmt) for s in self.tempfile_image_handler]
319 args = [s.format(**fmt) for s in self.tempfile_image_handler]
320 subprocess.call(args, stdout=devnull, stderr=devnull)
320 subprocess.call(args, stdout=devnull, stderr=devnull)
321
321
322 def handle_image_callable(self, data, mime):
322 def handle_image_callable(self, data, mime):
323 self.callable_image_handler(data)
323 self.callable_image_handler(data)
324
324
325 def handle_stdin_request(self, msg_id, timeout=0.1):
325 def handle_stdin_request(self, msg_id, timeout=0.1):
326 """ Method to capture raw_input
326 """ Method to capture raw_input
327 """
327 """
328 msg_rep = self.client.stdin_channel.get_msg(timeout=timeout)
328 msg_rep = self.client.stdin_channel.get_msg(timeout=timeout)
329 # in case any iopub came while we were waiting:
329 # in case any iopub came while we were waiting:
330 self.handle_iopub(msg_id)
330 self.handle_iopub(msg_id)
331 if msg_id == msg_rep["parent_header"].get("msg_id"):
331 if msg_id == msg_rep["parent_header"].get("msg_id"):
332 # wrap SIGINT handler
332 # wrap SIGINT handler
333 real_handler = signal.getsignal(signal.SIGINT)
333 real_handler = signal.getsignal(signal.SIGINT)
334 def double_int(sig,frame):
334 def double_int(sig,frame):
335 # call real handler (forwards sigint to kernel),
335 # call real handler (forwards sigint to kernel),
336 # then raise local interrupt, stopping local raw_input
336 # then raise local interrupt, stopping local raw_input
337 real_handler(sig,frame)
337 real_handler(sig,frame)
338 raise KeyboardInterrupt
338 raise KeyboardInterrupt
339 signal.signal(signal.SIGINT, double_int)
339 signal.signal(signal.SIGINT, double_int)
340
340
341 try:
341 try:
342 raw_data = input(msg_rep["content"]["prompt"])
342 raw_data = input(msg_rep["content"]["prompt"])
343 except EOFError:
343 except EOFError:
344 # turn EOFError into EOF character
344 # turn EOFError into EOF character
345 raw_data = '\x04'
345 raw_data = '\x04'
346 except KeyboardInterrupt:
346 except KeyboardInterrupt:
347 sys.stdout.write('\n')
347 sys.stdout.write('\n')
348 return
348 return
349 finally:
349 finally:
350 # restore SIGINT handler
350 # restore SIGINT handler
351 signal.signal(signal.SIGINT, real_handler)
351 signal.signal(signal.SIGINT, real_handler)
352
352
353 # only send stdin reply if there *was not* another request
353 # only send stdin reply if there *was not* another request
354 # or execution finished while we were reading.
354 # or execution finished while we were reading.
355 if not (self.client.stdin_channel.msg_ready() or self.client.shell_channel.msg_ready()):
355 if not (self.client.stdin_channel.msg_ready() or self.client.shell_channel.msg_ready()):
356 self.client.stdin_channel.input(raw_data)
356 self.client.stdin_channel.input(raw_data)
357
357
358 def mainloop(self, display_banner=False):
358 def mainloop(self, display_banner=False):
359 while True:
359 while True:
360 try:
360 try:
361 self.interact(display_banner=display_banner)
361 self.interact(display_banner=display_banner)
362 #self.interact_with_readline()
362 #self.interact_with_readline()
363 # XXX for testing of a readline-decoupled repl loop, call
363 # XXX for testing of a readline-decoupled repl loop, call
364 # interact_with_readline above
364 # interact_with_readline above
365 break
365 break
366 except KeyboardInterrupt:
366 except KeyboardInterrupt:
367 # this should not be necessary, but KeyboardInterrupt
367 # this should not be necessary, but KeyboardInterrupt
368 # handling seems rather unpredictable...
368 # handling seems rather unpredictable...
369 self.write("\nKeyboardInterrupt in interact()\n")
369 self.write("\nKeyboardInterrupt in interact()\n")
370
370
371 def wait_for_kernel(self, timeout=None):
371 def wait_for_kernel(self, timeout=None):
372 """method to wait for a kernel to be ready"""
372 """method to wait for a kernel to be ready"""
373 tic = time.time()
373 tic = time.time()
374 self.client.hb_channel.unpause()
374 self.client.hb_channel.unpause()
375 while True:
375 while True:
376 msg_id = self.client.kernel_info()
376 msg_id = self.client.kernel_info()
377 reply = None
377 reply = None
378 while True:
378 while True:
379 try:
379 try:
380 reply = self.client.get_shell_msg(timeout=1)
380 reply = self.client.get_shell_msg(timeout=1)
381 except Empty:
381 except Empty:
382 break
382 break
383 else:
383 else:
384 if reply['parent_header'].get('msg_id') == msg_id:
384 if reply['parent_header'].get('msg_id') == msg_id:
385 return True
385 return True
386 if timeout is not None \
386 if timeout is not None \
387 and (time.time() - tic) > timeout \
387 and (time.time() - tic) > timeout \
388 and not self.client.hb_channel.is_beating():
388 and not self.client.hb_channel.is_beating():
389 # heart failed
389 # heart failed
390 return False
390 return False
391 return True
391 return True
392
392
393 def interact(self, display_banner=None):
393 def interact(self, display_banner=None):
394 """Closely emulate the interactive Python console."""
394 """Closely emulate the interactive Python console."""
395
395
396 # batch run -> do not interact
396 # batch run -> do not interact
397 if self.exit_now:
397 if self.exit_now:
398 return
398 return
399
399
400 if display_banner is None:
400 if display_banner is None:
401 display_banner = self.display_banner
401 display_banner = self.display_banner
402
402
403 if isinstance(display_banner, string_types):
403 if isinstance(display_banner, string_types):
404 self.show_banner(display_banner)
404 self.show_banner(display_banner)
405 elif display_banner:
405 elif display_banner:
406 self.show_banner()
406 self.show_banner()
407
407
408 more = False
408 more = False
409
409
410 # run a non-empty no-op, so that we don't get a prompt until
410 # run a non-empty no-op, so that we don't get a prompt until
411 # we know the kernel is ready. This keeps the connection
411 # we know the kernel is ready. This keeps the connection
412 # message above the first prompt.
412 # message above the first prompt.
413 if not self.wait_for_kernel(self.kernel_timeout):
413 if not self.wait_for_kernel(self.kernel_timeout):
414 error("Kernel did not respond\n")
414 error("Kernel did not respond\n")
415 return
415 return
416
416
417 if self.has_readline:
417 if self.has_readline:
418 self.readline_startup_hook(self.pre_readline)
418 self.readline_startup_hook(self.pre_readline)
419 hlen_b4_cell = self.readline.get_current_history_length()
419 hlen_b4_cell = self.readline.get_current_history_length()
420 else:
420 else:
421 hlen_b4_cell = 0
421 hlen_b4_cell = 0
422 # exit_now is set by a call to %Exit or %Quit, through the
422 # exit_now is set by a call to %Exit or %Quit, through the
423 # ask_exit callback.
423 # ask_exit callback.
424
424
425 while not self.exit_now:
425 while not self.exit_now:
426 if not self.client.is_alive():
426 if not self.client.is_alive():
427 # kernel died, prompt for action or exit
427 # kernel died, prompt for action or exit
428
428
429 action = "restart" if self.manager else "wait for restart"
429 action = "restart" if self.manager else "wait for restart"
430 ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y')
430 ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y')
431 if ans:
431 if ans:
432 if self.manager:
432 if self.manager:
433 self.manager.restart_kernel(True)
433 self.manager.restart_kernel(True)
434 self.wait_for_kernel(self.kernel_timeout)
434 self.wait_for_kernel(self.kernel_timeout)
435 else:
435 else:
436 self.exit_now = True
436 self.exit_now = True
437 continue
437 continue
438 try:
438 try:
439 # protect prompt block from KeyboardInterrupt
439 # protect prompt block from KeyboardInterrupt
440 # when sitting on ctrl-C
440 # when sitting on ctrl-C
441 self.hooks.pre_prompt_hook()
441 self.hooks.pre_prompt_hook()
442 if more:
442 if more:
443 try:
443 try:
444 prompt = self.prompt_manager.render('in2')
444 prompt = self.prompt_manager.render('in2')
445 except Exception:
445 except Exception:
446 self.showtraceback()
446 self.showtraceback()
447 if self.autoindent:
447 if self.autoindent:
448 self.rl_do_indent = True
448 self.rl_do_indent = True
449
449
450 else:
450 else:
451 try:
451 try:
452 prompt = self.separate_in + self.prompt_manager.render('in')
452 prompt = self.separate_in + self.prompt_manager.render('in')
453 except Exception:
453 except Exception:
454 self.showtraceback()
454 self.showtraceback()
455
455
456 line = self.raw_input(prompt)
456 line = self.raw_input(prompt)
457 if self.exit_now:
457 if self.exit_now:
458 # quick exit on sys.std[in|out] close
458 # quick exit on sys.std[in|out] close
459 break
459 break
460 if self.autoindent:
460 if self.autoindent:
461 self.rl_do_indent = False
461 self.rl_do_indent = False
462
462
463 except KeyboardInterrupt:
463 except KeyboardInterrupt:
464 #double-guard against keyboardinterrupts during kbdint handling
464 #double-guard against keyboardinterrupts during kbdint handling
465 try:
465 try:
466 self.write('\nKeyboardInterrupt\n')
466 self.write('\nKeyboardInterrupt\n')
467 source_raw = self.input_splitter.source_raw_reset()[1]
467 source_raw = self.input_splitter.raw_reset()
468 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
468 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
469 more = False
469 more = False
470 except KeyboardInterrupt:
470 except KeyboardInterrupt:
471 pass
471 pass
472 except EOFError:
472 except EOFError:
473 if self.autoindent:
473 if self.autoindent:
474 self.rl_do_indent = False
474 self.rl_do_indent = False
475 if self.has_readline:
475 if self.has_readline:
476 self.readline_startup_hook(None)
476 self.readline_startup_hook(None)
477 self.write('\n')
477 self.write('\n')
478 self.exit()
478 self.exit()
479 except bdb.BdbQuit:
479 except bdb.BdbQuit:
480 warn('The Python debugger has exited with a BdbQuit exception.\n'
480 warn('The Python debugger has exited with a BdbQuit exception.\n'
481 'Because of how pdb handles the stack, it is impossible\n'
481 'Because of how pdb handles the stack, it is impossible\n'
482 'for IPython to properly format this particular exception.\n'
482 'for IPython to properly format this particular exception.\n'
483 'IPython will resume normal operation.')
483 'IPython will resume normal operation.')
484 except:
484 except:
485 # exceptions here are VERY RARE, but they can be triggered
485 # exceptions here are VERY RARE, but they can be triggered
486 # asynchronously by signal handlers, for example.
486 # asynchronously by signal handlers, for example.
487 self.showtraceback()
487 self.showtraceback()
488 else:
488 else:
489 self.input_splitter.push(line)
489 try:
490 more = self.input_splitter.push_accepts_more()
490 self.input_splitter.push(line)
491 more = self.input_splitter.push_accepts_more()
492 except SyntaxError:
493 # Run the code directly - run_cell takes care of displaying
494 # the exception.
495 more = False
491 if (self.SyntaxTB.last_syntax_error and
496 if (self.SyntaxTB.last_syntax_error and
492 self.autoedit_syntax):
497 self.autoedit_syntax):
493 self.edit_syntax_error()
498 self.edit_syntax_error()
494 if not more:
499 if not more:
495 source_raw = self.input_splitter.source_raw_reset()[1]
500 source_raw = self.input_splitter.raw_reset()
496 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
501 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
497 self.run_cell(source_raw)
502 self.run_cell(source_raw)
498
503
499
504
500 # Turn off the exit flag, so the mainloop can be restarted if desired
505 # Turn off the exit flag, so the mainloop can be restarted if desired
501 self.exit_now = False
506 self.exit_now = False
@@ -1,697 +1,702 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Subclass of InteractiveShell for terminal based frontends."""
2 """Subclass of InteractiveShell for terminal based frontends."""
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-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 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 from __future__ import print_function
16 from __future__ import print_function
17
17
18 import bdb
18 import bdb
19 import os
19 import os
20 import sys
20 import sys
21
21
22 from IPython.core.error import TryNext, UsageError
22 from IPython.core.error import TryNext, UsageError
23 from IPython.core.usage import interactive_usage, default_banner
23 from IPython.core.usage import interactive_usage, default_banner
24 from IPython.core.inputsplitter import IPythonInputSplitter
24 from IPython.core.inputsplitter import IPythonInputSplitter
25 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
25 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
26 from IPython.core.magic import Magics, magics_class, line_magic
26 from IPython.core.magic import Magics, magics_class, line_magic
27 from IPython.lib.clipboard import ClipboardEmpty
27 from IPython.lib.clipboard import ClipboardEmpty
28 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.testing.skipdoctest import skip_doctest
29 from IPython.utils.encoding import get_stream_enc
29 from IPython.utils.encoding import get_stream_enc
30 from IPython.utils import py3compat
30 from IPython.utils import py3compat
31 from IPython.utils.terminal import toggle_set_term_title, set_term_title
31 from IPython.utils.terminal import toggle_set_term_title, set_term_title
32 from IPython.utils.process import abbrev_cwd
32 from IPython.utils.process import abbrev_cwd
33 from IPython.utils.warn import warn, error
33 from IPython.utils.warn import warn, error
34 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
34 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
35 from IPython.utils.traitlets import Integer, CBool, Unicode
35 from IPython.utils.traitlets import Integer, CBool, Unicode
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Utilities
38 # Utilities
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40
40
41 def get_default_editor():
41 def get_default_editor():
42 try:
42 try:
43 ed = os.environ['EDITOR']
43 ed = os.environ['EDITOR']
44 if not py3compat.PY3:
44 if not py3compat.PY3:
45 ed = ed.decode()
45 ed = ed.decode()
46 return ed
46 return ed
47 except KeyError:
47 except KeyError:
48 pass
48 pass
49 except UnicodeError:
49 except UnicodeError:
50 warn("$EDITOR environment variable is not pure ASCII. Using platform "
50 warn("$EDITOR environment variable is not pure ASCII. Using platform "
51 "default editor.")
51 "default editor.")
52
52
53 if os.name == 'posix':
53 if os.name == 'posix':
54 return 'vi' # the only one guaranteed to be there!
54 return 'vi' # the only one guaranteed to be there!
55 else:
55 else:
56 return 'notepad' # same in Windows!
56 return 'notepad' # same in Windows!
57
57
58 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
58 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
59 """ Yield pasted lines until the user enters the given sentinel value.
59 """ Yield pasted lines until the user enters the given sentinel value.
60 """
60 """
61 if not quiet:
61 if not quiet:
62 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
62 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
63 % sentinel)
63 % sentinel)
64 prompt = ":"
64 prompt = ":"
65 else:
65 else:
66 prompt = ""
66 prompt = ""
67 while True:
67 while True:
68 try:
68 try:
69 l = l_input(prompt)
69 l = l_input(prompt)
70 if l == sentinel:
70 if l == sentinel:
71 return
71 return
72 else:
72 else:
73 yield l
73 yield l
74 except EOFError:
74 except EOFError:
75 print('<EOF>')
75 print('<EOF>')
76 return
76 return
77
77
78
78
79 #------------------------------------------------------------------------
79 #------------------------------------------------------------------------
80 # Terminal-specific magics
80 # Terminal-specific magics
81 #------------------------------------------------------------------------
81 #------------------------------------------------------------------------
82
82
83 @magics_class
83 @magics_class
84 class TerminalMagics(Magics):
84 class TerminalMagics(Magics):
85 def __init__(self, shell):
85 def __init__(self, shell):
86 super(TerminalMagics, self).__init__(shell)
86 super(TerminalMagics, self).__init__(shell)
87 self.input_splitter = IPythonInputSplitter()
87 self.input_splitter = IPythonInputSplitter()
88
88
89 def store_or_execute(self, block, name):
89 def store_or_execute(self, block, name):
90 """ Execute a block, or store it in a variable, per the user's request.
90 """ Execute a block, or store it in a variable, per the user's request.
91 """
91 """
92 if name:
92 if name:
93 # If storing it for further editing
93 # If storing it for further editing
94 self.shell.user_ns[name] = SList(block.splitlines())
94 self.shell.user_ns[name] = SList(block.splitlines())
95 print("Block assigned to '%s'" % name)
95 print("Block assigned to '%s'" % name)
96 else:
96 else:
97 b = self.preclean_input(block)
97 b = self.preclean_input(block)
98 self.shell.user_ns['pasted_block'] = b
98 self.shell.user_ns['pasted_block'] = b
99 self.shell.using_paste_magics = True
99 self.shell.using_paste_magics = True
100 try:
100 try:
101 self.shell.run_cell(b)
101 self.shell.run_cell(b)
102 finally:
102 finally:
103 self.shell.using_paste_magics = False
103 self.shell.using_paste_magics = False
104
104
105 def preclean_input(self, block):
105 def preclean_input(self, block):
106 lines = block.splitlines()
106 lines = block.splitlines()
107 while lines and not lines[0].strip():
107 while lines and not lines[0].strip():
108 lines = lines[1:]
108 lines = lines[1:]
109 return strip_email_quotes('\n'.join(lines))
109 return strip_email_quotes('\n'.join(lines))
110
110
111 def rerun_pasted(self, name='pasted_block'):
111 def rerun_pasted(self, name='pasted_block'):
112 """ Rerun a previously pasted command.
112 """ Rerun a previously pasted command.
113 """
113 """
114 b = self.shell.user_ns.get(name)
114 b = self.shell.user_ns.get(name)
115
115
116 # Sanity checks
116 # Sanity checks
117 if b is None:
117 if b is None:
118 raise UsageError('No previous pasted block available')
118 raise UsageError('No previous pasted block available')
119 if not isinstance(b, py3compat.string_types):
119 if not isinstance(b, py3compat.string_types):
120 raise UsageError(
120 raise UsageError(
121 "Variable 'pasted_block' is not a string, can't execute")
121 "Variable 'pasted_block' is not a string, can't execute")
122
122
123 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
123 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
124 self.shell.run_cell(b)
124 self.shell.run_cell(b)
125
125
126 @line_magic
126 @line_magic
127 def autoindent(self, parameter_s = ''):
127 def autoindent(self, parameter_s = ''):
128 """Toggle autoindent on/off (if available)."""
128 """Toggle autoindent on/off (if available)."""
129
129
130 self.shell.set_autoindent()
130 self.shell.set_autoindent()
131 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
131 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
132
132
133 @skip_doctest
133 @skip_doctest
134 @line_magic
134 @line_magic
135 def cpaste(self, parameter_s=''):
135 def cpaste(self, parameter_s=''):
136 """Paste & execute a pre-formatted code block from clipboard.
136 """Paste & execute a pre-formatted code block from clipboard.
137
137
138 You must terminate the block with '--' (two minus-signs) or Ctrl-D
138 You must terminate the block with '--' (two minus-signs) or Ctrl-D
139 alone on the line. You can also provide your own sentinel with '%paste
139 alone on the line. You can also provide your own sentinel with '%paste
140 -s %%' ('%%' is the new sentinel for this operation).
140 -s %%' ('%%' is the new sentinel for this operation).
141
141
142 The block is dedented prior to execution to enable execution of method
142 The block is dedented prior to execution to enable execution of method
143 definitions. '>' and '+' characters at the beginning of a line are
143 definitions. '>' and '+' characters at the beginning of a line are
144 ignored, to allow pasting directly from e-mails, diff files and
144 ignored, to allow pasting directly from e-mails, diff files and
145 doctests (the '...' continuation prompt is also stripped). The
145 doctests (the '...' continuation prompt is also stripped). The
146 executed block is also assigned to variable named 'pasted_block' for
146 executed block is also assigned to variable named 'pasted_block' for
147 later editing with '%edit pasted_block'.
147 later editing with '%edit pasted_block'.
148
148
149 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
149 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
150 This assigns the pasted block to variable 'foo' as string, without
150 This assigns the pasted block to variable 'foo' as string, without
151 dedenting or executing it (preceding >>> and + is still stripped)
151 dedenting or executing it (preceding >>> and + is still stripped)
152
152
153 '%cpaste -r' re-executes the block previously entered by cpaste.
153 '%cpaste -r' re-executes the block previously entered by cpaste.
154 '%cpaste -q' suppresses any additional output messages.
154 '%cpaste -q' suppresses any additional output messages.
155
155
156 Do not be alarmed by garbled output on Windows (it's a readline bug).
156 Do not be alarmed by garbled output on Windows (it's a readline bug).
157 Just press enter and type -- (and press enter again) and the block
157 Just press enter and type -- (and press enter again) and the block
158 will be what was just pasted.
158 will be what was just pasted.
159
159
160 IPython statements (magics, shell escapes) are not supported (yet).
160 IPython statements (magics, shell escapes) are not supported (yet).
161
161
162 See also
162 See also
163 --------
163 --------
164 paste: automatically pull code from clipboard.
164 paste: automatically pull code from clipboard.
165
165
166 Examples
166 Examples
167 --------
167 --------
168 ::
168 ::
169
169
170 In [8]: %cpaste
170 In [8]: %cpaste
171 Pasting code; enter '--' alone on the line to stop.
171 Pasting code; enter '--' alone on the line to stop.
172 :>>> a = ["world!", "Hello"]
172 :>>> a = ["world!", "Hello"]
173 :>>> print " ".join(sorted(a))
173 :>>> print " ".join(sorted(a))
174 :--
174 :--
175 Hello world!
175 Hello world!
176 """
176 """
177 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
177 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
178 if 'r' in opts:
178 if 'r' in opts:
179 self.rerun_pasted()
179 self.rerun_pasted()
180 return
180 return
181
181
182 quiet = ('q' in opts)
182 quiet = ('q' in opts)
183
183
184 sentinel = opts.get('s', '--')
184 sentinel = opts.get('s', '--')
185 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
185 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
186 self.store_or_execute(block, name)
186 self.store_or_execute(block, name)
187
187
188 @line_magic
188 @line_magic
189 def paste(self, parameter_s=''):
189 def paste(self, parameter_s=''):
190 """Paste & execute a pre-formatted code block from clipboard.
190 """Paste & execute a pre-formatted code block from clipboard.
191
191
192 The text is pulled directly from the clipboard without user
192 The text is pulled directly from the clipboard without user
193 intervention and printed back on the screen before execution (unless
193 intervention and printed back on the screen before execution (unless
194 the -q flag is given to force quiet mode).
194 the -q flag is given to force quiet mode).
195
195
196 The block is dedented prior to execution to enable execution of method
196 The block is dedented prior to execution to enable execution of method
197 definitions. '>' and '+' characters at the beginning of a line are
197 definitions. '>' and '+' characters at the beginning of a line are
198 ignored, to allow pasting directly from e-mails, diff files and
198 ignored, to allow pasting directly from e-mails, diff files and
199 doctests (the '...' continuation prompt is also stripped). The
199 doctests (the '...' continuation prompt is also stripped). The
200 executed block is also assigned to variable named 'pasted_block' for
200 executed block is also assigned to variable named 'pasted_block' for
201 later editing with '%edit pasted_block'.
201 later editing with '%edit pasted_block'.
202
202
203 You can also pass a variable name as an argument, e.g. '%paste foo'.
203 You can also pass a variable name as an argument, e.g. '%paste foo'.
204 This assigns the pasted block to variable 'foo' as string, without
204 This assigns the pasted block to variable 'foo' as string, without
205 executing it (preceding >>> and + is still stripped).
205 executing it (preceding >>> and + is still stripped).
206
206
207 Options:
207 Options:
208
208
209 -r: re-executes the block previously entered by cpaste.
209 -r: re-executes the block previously entered by cpaste.
210
210
211 -q: quiet mode: do not echo the pasted text back to the terminal.
211 -q: quiet mode: do not echo the pasted text back to the terminal.
212
212
213 IPython statements (magics, shell escapes) are not supported (yet).
213 IPython statements (magics, shell escapes) are not supported (yet).
214
214
215 See also
215 See also
216 --------
216 --------
217 cpaste: manually paste code into terminal until you mark its end.
217 cpaste: manually paste code into terminal until you mark its end.
218 """
218 """
219 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
219 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
220 if 'r' in opts:
220 if 'r' in opts:
221 self.rerun_pasted()
221 self.rerun_pasted()
222 return
222 return
223 try:
223 try:
224 block = self.shell.hooks.clipboard_get()
224 block = self.shell.hooks.clipboard_get()
225 except TryNext as clipboard_exc:
225 except TryNext as clipboard_exc:
226 message = getattr(clipboard_exc, 'args')
226 message = getattr(clipboard_exc, 'args')
227 if message:
227 if message:
228 error(message[0])
228 error(message[0])
229 else:
229 else:
230 error('Could not get text from the clipboard.')
230 error('Could not get text from the clipboard.')
231 return
231 return
232 except ClipboardEmpty:
232 except ClipboardEmpty:
233 raise UsageError("The clipboard appears to be empty")
233 raise UsageError("The clipboard appears to be empty")
234
234
235 # By default, echo back to terminal unless quiet mode is requested
235 # By default, echo back to terminal unless quiet mode is requested
236 if 'q' not in opts:
236 if 'q' not in opts:
237 write = self.shell.write
237 write = self.shell.write
238 write(self.shell.pycolorize(block))
238 write(self.shell.pycolorize(block))
239 if not block.endswith('\n'):
239 if not block.endswith('\n'):
240 write('\n')
240 write('\n')
241 write("## -- End pasted text --\n")
241 write("## -- End pasted text --\n")
242
242
243 self.store_or_execute(block, name)
243 self.store_or_execute(block, name)
244
244
245 # Class-level: add a '%cls' magic only on Windows
245 # Class-level: add a '%cls' magic only on Windows
246 if sys.platform == 'win32':
246 if sys.platform == 'win32':
247 @line_magic
247 @line_magic
248 def cls(self, s):
248 def cls(self, s):
249 """Clear screen.
249 """Clear screen.
250 """
250 """
251 os.system("cls")
251 os.system("cls")
252
252
253 #-----------------------------------------------------------------------------
253 #-----------------------------------------------------------------------------
254 # Main class
254 # Main class
255 #-----------------------------------------------------------------------------
255 #-----------------------------------------------------------------------------
256
256
257 class TerminalInteractiveShell(InteractiveShell):
257 class TerminalInteractiveShell(InteractiveShell):
258
258
259 autoedit_syntax = CBool(False, config=True,
259 autoedit_syntax = CBool(False, config=True,
260 help="auto editing of files with syntax errors.")
260 help="auto editing of files with syntax errors.")
261 banner = Unicode('')
261 banner = Unicode('')
262 banner1 = Unicode(default_banner, config=True,
262 banner1 = Unicode(default_banner, config=True,
263 help="""The part of the banner to be printed before the profile"""
263 help="""The part of the banner to be printed before the profile"""
264 )
264 )
265 banner2 = Unicode('', config=True,
265 banner2 = Unicode('', config=True,
266 help="""The part of the banner to be printed after the profile"""
266 help="""The part of the banner to be printed after the profile"""
267 )
267 )
268 confirm_exit = CBool(True, config=True,
268 confirm_exit = CBool(True, config=True,
269 help="""
269 help="""
270 Set to confirm when you try to exit IPython with an EOF (Control-D
270 Set to confirm when you try to exit IPython with an EOF (Control-D
271 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
271 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
272 you can force a direct exit without any confirmation.""",
272 you can force a direct exit without any confirmation.""",
273 )
273 )
274 # This display_banner only controls whether or not self.show_banner()
274 # This display_banner only controls whether or not self.show_banner()
275 # is called when mainloop/interact are called. The default is False
275 # is called when mainloop/interact are called. The default is False
276 # because for the terminal based application, the banner behavior
276 # because for the terminal based application, the banner behavior
277 # is controlled by Global.display_banner, which IPythonApp looks at
277 # is controlled by Global.display_banner, which IPythonApp looks at
278 # to determine if *it* should call show_banner() by hand or not.
278 # to determine if *it* should call show_banner() by hand or not.
279 display_banner = CBool(False) # This isn't configurable!
279 display_banner = CBool(False) # This isn't configurable!
280 embedded = CBool(False)
280 embedded = CBool(False)
281 embedded_active = CBool(False)
281 embedded_active = CBool(False)
282 editor = Unicode(get_default_editor(), config=True,
282 editor = Unicode(get_default_editor(), config=True,
283 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
283 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
284 )
284 )
285 pager = Unicode('less', config=True,
285 pager = Unicode('less', config=True,
286 help="The shell program to be used for paging.")
286 help="The shell program to be used for paging.")
287
287
288 screen_length = Integer(0, config=True,
288 screen_length = Integer(0, config=True,
289 help=
289 help=
290 """Number of lines of your screen, used to control printing of very
290 """Number of lines of your screen, used to control printing of very
291 long strings. Strings longer than this number of lines will be sent
291 long strings. Strings longer than this number of lines will be sent
292 through a pager instead of directly printed. The default value for
292 through a pager instead of directly printed. The default value for
293 this is 0, which means IPython will auto-detect your screen size every
293 this is 0, which means IPython will auto-detect your screen size every
294 time it needs to print certain potentially long strings (this doesn't
294 time it needs to print certain potentially long strings (this doesn't
295 change the behavior of the 'print' keyword, it's only triggered
295 change the behavior of the 'print' keyword, it's only triggered
296 internally). If for some reason this isn't working well (it needs
296 internally). If for some reason this isn't working well (it needs
297 curses support), specify it yourself. Otherwise don't change the
297 curses support), specify it yourself. Otherwise don't change the
298 default.""",
298 default.""",
299 )
299 )
300 term_title = CBool(False, config=True,
300 term_title = CBool(False, config=True,
301 help="Enable auto setting the terminal title."
301 help="Enable auto setting the terminal title."
302 )
302 )
303
303
304 # This `using_paste_magics` is used to detect whether the code is being
304 # This `using_paste_magics` is used to detect whether the code is being
305 # executed via paste magics functions
305 # executed via paste magics functions
306 using_paste_magics = CBool(False)
306 using_paste_magics = CBool(False)
307
307
308 # In the terminal, GUI control is done via PyOS_InputHook
308 # In the terminal, GUI control is done via PyOS_InputHook
309 @staticmethod
309 @staticmethod
310 def enable_gui(gui=None, app=None):
310 def enable_gui(gui=None, app=None):
311 """Switch amongst GUI input hooks by name.
311 """Switch amongst GUI input hooks by name.
312 """
312 """
313 # Deferred import
313 # Deferred import
314 from IPython.lib.inputhook import enable_gui as real_enable_gui
314 from IPython.lib.inputhook import enable_gui as real_enable_gui
315 try:
315 try:
316 return real_enable_gui(gui, app)
316 return real_enable_gui(gui, app)
317 except ValueError as e:
317 except ValueError as e:
318 raise UsageError("%s" % e)
318 raise UsageError("%s" % e)
319
319
320 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
320 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
321 user_ns=None, user_module=None, custom_exceptions=((),None),
321 user_ns=None, user_module=None, custom_exceptions=((),None),
322 usage=None, banner1=None, banner2=None, display_banner=None,
322 usage=None, banner1=None, banner2=None, display_banner=None,
323 **kwargs):
323 **kwargs):
324
324
325 super(TerminalInteractiveShell, self).__init__(
325 super(TerminalInteractiveShell, self).__init__(
326 config=config, ipython_dir=ipython_dir, profile_dir=profile_dir, user_ns=user_ns,
326 config=config, ipython_dir=ipython_dir, profile_dir=profile_dir, user_ns=user_ns,
327 user_module=user_module, custom_exceptions=custom_exceptions,
327 user_module=user_module, custom_exceptions=custom_exceptions,
328 **kwargs
328 **kwargs
329 )
329 )
330 # use os.system instead of utils.process.system by default,
330 # use os.system instead of utils.process.system by default,
331 # because piped system doesn't make sense in the Terminal:
331 # because piped system doesn't make sense in the Terminal:
332 self.system = self.system_raw
332 self.system = self.system_raw
333
333
334 self.init_term_title()
334 self.init_term_title()
335 self.init_usage(usage)
335 self.init_usage(usage)
336 self.init_banner(banner1, banner2, display_banner)
336 self.init_banner(banner1, banner2, display_banner)
337
337
338 #-------------------------------------------------------------------------
338 #-------------------------------------------------------------------------
339 # Overrides of init stages
339 # Overrides of init stages
340 #-------------------------------------------------------------------------
340 #-------------------------------------------------------------------------
341
341
342 def init_display_formatter(self):
342 def init_display_formatter(self):
343 super(TerminalInteractiveShell, self).init_display_formatter()
343 super(TerminalInteractiveShell, self).init_display_formatter()
344 # terminal only supports plaintext
344 # terminal only supports plaintext
345 self.display_formatter.active_types = ['text/plain']
345 self.display_formatter.active_types = ['text/plain']
346
346
347 #-------------------------------------------------------------------------
347 #-------------------------------------------------------------------------
348 # Things related to the terminal
348 # Things related to the terminal
349 #-------------------------------------------------------------------------
349 #-------------------------------------------------------------------------
350
350
351 @property
351 @property
352 def usable_screen_length(self):
352 def usable_screen_length(self):
353 if self.screen_length == 0:
353 if self.screen_length == 0:
354 return 0
354 return 0
355 else:
355 else:
356 num_lines_bot = self.separate_in.count('\n')+1
356 num_lines_bot = self.separate_in.count('\n')+1
357 return self.screen_length - num_lines_bot
357 return self.screen_length - num_lines_bot
358
358
359 def init_term_title(self):
359 def init_term_title(self):
360 # Enable or disable the terminal title.
360 # Enable or disable the terminal title.
361 if self.term_title:
361 if self.term_title:
362 toggle_set_term_title(True)
362 toggle_set_term_title(True)
363 set_term_title('IPython: ' + abbrev_cwd())
363 set_term_title('IPython: ' + abbrev_cwd())
364 else:
364 else:
365 toggle_set_term_title(False)
365 toggle_set_term_title(False)
366
366
367 #-------------------------------------------------------------------------
367 #-------------------------------------------------------------------------
368 # Things related to aliases
368 # Things related to aliases
369 #-------------------------------------------------------------------------
369 #-------------------------------------------------------------------------
370
370
371 def init_alias(self):
371 def init_alias(self):
372 # The parent class defines aliases that can be safely used with any
372 # The parent class defines aliases that can be safely used with any
373 # frontend.
373 # frontend.
374 super(TerminalInteractiveShell, self).init_alias()
374 super(TerminalInteractiveShell, self).init_alias()
375
375
376 # Now define aliases that only make sense on the terminal, because they
376 # Now define aliases that only make sense on the terminal, because they
377 # need direct access to the console in a way that we can't emulate in
377 # need direct access to the console in a way that we can't emulate in
378 # GUI or web frontend
378 # GUI or web frontend
379 if os.name == 'posix':
379 if os.name == 'posix':
380 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
380 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
381 ('man', 'man')]
381 ('man', 'man')]
382 else :
382 else :
383 aliases = []
383 aliases = []
384
384
385 for name, cmd in aliases:
385 for name, cmd in aliases:
386 self.alias_manager.soft_define_alias(name, cmd)
386 self.alias_manager.soft_define_alias(name, cmd)
387
387
388 #-------------------------------------------------------------------------
388 #-------------------------------------------------------------------------
389 # Things related to the banner and usage
389 # Things related to the banner and usage
390 #-------------------------------------------------------------------------
390 #-------------------------------------------------------------------------
391
391
392 def _banner1_changed(self):
392 def _banner1_changed(self):
393 self.compute_banner()
393 self.compute_banner()
394
394
395 def _banner2_changed(self):
395 def _banner2_changed(self):
396 self.compute_banner()
396 self.compute_banner()
397
397
398 def _term_title_changed(self, name, new_value):
398 def _term_title_changed(self, name, new_value):
399 self.init_term_title()
399 self.init_term_title()
400
400
401 def init_banner(self, banner1, banner2, display_banner):
401 def init_banner(self, banner1, banner2, display_banner):
402 if banner1 is not None:
402 if banner1 is not None:
403 self.banner1 = banner1
403 self.banner1 = banner1
404 if banner2 is not None:
404 if banner2 is not None:
405 self.banner2 = banner2
405 self.banner2 = banner2
406 if display_banner is not None:
406 if display_banner is not None:
407 self.display_banner = display_banner
407 self.display_banner = display_banner
408 self.compute_banner()
408 self.compute_banner()
409
409
410 def show_banner(self, banner=None):
410 def show_banner(self, banner=None):
411 if banner is None:
411 if banner is None:
412 banner = self.banner
412 banner = self.banner
413 self.write(banner)
413 self.write(banner)
414
414
415 def compute_banner(self):
415 def compute_banner(self):
416 self.banner = self.banner1
416 self.banner = self.banner1
417 if self.profile and self.profile != 'default':
417 if self.profile and self.profile != 'default':
418 self.banner += '\nIPython profile: %s\n' % self.profile
418 self.banner += '\nIPython profile: %s\n' % self.profile
419 if self.banner2:
419 if self.banner2:
420 self.banner += '\n' + self.banner2
420 self.banner += '\n' + self.banner2
421
421
422 def init_usage(self, usage=None):
422 def init_usage(self, usage=None):
423 if usage is None:
423 if usage is None:
424 self.usage = interactive_usage
424 self.usage = interactive_usage
425 else:
425 else:
426 self.usage = usage
426 self.usage = usage
427
427
428 #-------------------------------------------------------------------------
428 #-------------------------------------------------------------------------
429 # Mainloop and code execution logic
429 # Mainloop and code execution logic
430 #-------------------------------------------------------------------------
430 #-------------------------------------------------------------------------
431
431
432 def mainloop(self, display_banner=None):
432 def mainloop(self, display_banner=None):
433 """Start the mainloop.
433 """Start the mainloop.
434
434
435 If an optional banner argument is given, it will override the
435 If an optional banner argument is given, it will override the
436 internally created default banner.
436 internally created default banner.
437 """
437 """
438
438
439 with self.builtin_trap, self.display_trap:
439 with self.builtin_trap, self.display_trap:
440
440
441 while 1:
441 while 1:
442 try:
442 try:
443 self.interact(display_banner=display_banner)
443 self.interact(display_banner=display_banner)
444 #self.interact_with_readline()
444 #self.interact_with_readline()
445 # XXX for testing of a readline-decoupled repl loop, call
445 # XXX for testing of a readline-decoupled repl loop, call
446 # interact_with_readline above
446 # interact_with_readline above
447 break
447 break
448 except KeyboardInterrupt:
448 except KeyboardInterrupt:
449 # this should not be necessary, but KeyboardInterrupt
449 # this should not be necessary, but KeyboardInterrupt
450 # handling seems rather unpredictable...
450 # handling seems rather unpredictable...
451 self.write("\nKeyboardInterrupt in interact()\n")
451 self.write("\nKeyboardInterrupt in interact()\n")
452
452
453 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
453 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
454 """Store multiple lines as a single entry in history"""
454 """Store multiple lines as a single entry in history"""
455
455
456 # do nothing without readline or disabled multiline
456 # do nothing without readline or disabled multiline
457 if not self.has_readline or not self.multiline_history:
457 if not self.has_readline or not self.multiline_history:
458 return hlen_before_cell
458 return hlen_before_cell
459
459
460 # windows rl has no remove_history_item
460 # windows rl has no remove_history_item
461 if not hasattr(self.readline, "remove_history_item"):
461 if not hasattr(self.readline, "remove_history_item"):
462 return hlen_before_cell
462 return hlen_before_cell
463
463
464 # skip empty cells
464 # skip empty cells
465 if not source_raw.rstrip():
465 if not source_raw.rstrip():
466 return hlen_before_cell
466 return hlen_before_cell
467
467
468 # nothing changed do nothing, e.g. when rl removes consecutive dups
468 # nothing changed do nothing, e.g. when rl removes consecutive dups
469 hlen = self.readline.get_current_history_length()
469 hlen = self.readline.get_current_history_length()
470 if hlen == hlen_before_cell:
470 if hlen == hlen_before_cell:
471 return hlen_before_cell
471 return hlen_before_cell
472
472
473 for i in range(hlen - hlen_before_cell):
473 for i in range(hlen - hlen_before_cell):
474 self.readline.remove_history_item(hlen - i - 1)
474 self.readline.remove_history_item(hlen - i - 1)
475 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
475 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
476 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
476 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
477 stdin_encoding))
477 stdin_encoding))
478 return self.readline.get_current_history_length()
478 return self.readline.get_current_history_length()
479
479
480 def interact(self, display_banner=None):
480 def interact(self, display_banner=None):
481 """Closely emulate the interactive Python console."""
481 """Closely emulate the interactive Python console."""
482
482
483 # batch run -> do not interact
483 # batch run -> do not interact
484 if self.exit_now:
484 if self.exit_now:
485 return
485 return
486
486
487 if display_banner is None:
487 if display_banner is None:
488 display_banner = self.display_banner
488 display_banner = self.display_banner
489
489
490 if isinstance(display_banner, py3compat.string_types):
490 if isinstance(display_banner, py3compat.string_types):
491 self.show_banner(display_banner)
491 self.show_banner(display_banner)
492 elif display_banner:
492 elif display_banner:
493 self.show_banner()
493 self.show_banner()
494
494
495 more = False
495 more = False
496
496
497 if self.has_readline:
497 if self.has_readline:
498 self.readline_startup_hook(self.pre_readline)
498 self.readline_startup_hook(self.pre_readline)
499 hlen_b4_cell = self.readline.get_current_history_length()
499 hlen_b4_cell = self.readline.get_current_history_length()
500 else:
500 else:
501 hlen_b4_cell = 0
501 hlen_b4_cell = 0
502 # exit_now is set by a call to %Exit or %Quit, through the
502 # exit_now is set by a call to %Exit or %Quit, through the
503 # ask_exit callback.
503 # ask_exit callback.
504
504
505 while not self.exit_now:
505 while not self.exit_now:
506 self.hooks.pre_prompt_hook()
506 self.hooks.pre_prompt_hook()
507 if more:
507 if more:
508 try:
508 try:
509 prompt = self.prompt_manager.render('in2')
509 prompt = self.prompt_manager.render('in2')
510 except:
510 except:
511 self.showtraceback()
511 self.showtraceback()
512 if self.autoindent:
512 if self.autoindent:
513 self.rl_do_indent = True
513 self.rl_do_indent = True
514
514
515 else:
515 else:
516 try:
516 try:
517 prompt = self.separate_in + self.prompt_manager.render('in')
517 prompt = self.separate_in + self.prompt_manager.render('in')
518 except:
518 except:
519 self.showtraceback()
519 self.showtraceback()
520 try:
520 try:
521 line = self.raw_input(prompt)
521 line = self.raw_input(prompt)
522 if self.exit_now:
522 if self.exit_now:
523 # quick exit on sys.std[in|out] close
523 # quick exit on sys.std[in|out] close
524 break
524 break
525 if self.autoindent:
525 if self.autoindent:
526 self.rl_do_indent = False
526 self.rl_do_indent = False
527
527
528 except KeyboardInterrupt:
528 except KeyboardInterrupt:
529 #double-guard against keyboardinterrupts during kbdint handling
529 #double-guard against keyboardinterrupts during kbdint handling
530 try:
530 try:
531 self.write('\nKeyboardInterrupt\n')
531 self.write('\nKeyboardInterrupt\n')
532 source_raw = self.input_splitter.source_raw_reset()[1]
532 source_raw = self.input_splitter.raw_reset()
533 hlen_b4_cell = \
533 hlen_b4_cell = \
534 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
534 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
535 more = False
535 more = False
536 except KeyboardInterrupt:
536 except KeyboardInterrupt:
537 pass
537 pass
538 except EOFError:
538 except EOFError:
539 if self.autoindent:
539 if self.autoindent:
540 self.rl_do_indent = False
540 self.rl_do_indent = False
541 if self.has_readline:
541 if self.has_readline:
542 self.readline_startup_hook(None)
542 self.readline_startup_hook(None)
543 self.write('\n')
543 self.write('\n')
544 self.exit()
544 self.exit()
545 except bdb.BdbQuit:
545 except bdb.BdbQuit:
546 warn('The Python debugger has exited with a BdbQuit exception.\n'
546 warn('The Python debugger has exited with a BdbQuit exception.\n'
547 'Because of how pdb handles the stack, it is impossible\n'
547 'Because of how pdb handles the stack, it is impossible\n'
548 'for IPython to properly format this particular exception.\n'
548 'for IPython to properly format this particular exception.\n'
549 'IPython will resume normal operation.')
549 'IPython will resume normal operation.')
550 except:
550 except:
551 # exceptions here are VERY RARE, but they can be triggered
551 # exceptions here are VERY RARE, but they can be triggered
552 # asynchronously by signal handlers, for example.
552 # asynchronously by signal handlers, for example.
553 self.showtraceback()
553 self.showtraceback()
554 else:
554 else:
555 self.input_splitter.push(line)
555 try:
556 more = self.input_splitter.push_accepts_more()
556 self.input_splitter.push(line)
557 more = self.input_splitter.push_accepts_more()
558 except SyntaxError:
559 # Run the code directly - run_cell takes care of displaying
560 # the exception.
561 more = False
557 if (self.SyntaxTB.last_syntax_error and
562 if (self.SyntaxTB.last_syntax_error and
558 self.autoedit_syntax):
563 self.autoedit_syntax):
559 self.edit_syntax_error()
564 self.edit_syntax_error()
560 if not more:
565 if not more:
561 source_raw = self.input_splitter.source_raw_reset()[1]
566 source_raw = self.input_splitter.raw_reset()
562 self.run_cell(source_raw, store_history=True)
567 self.run_cell(source_raw, store_history=True)
563 hlen_b4_cell = \
568 hlen_b4_cell = \
564 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
569 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
565
570
566 # Turn off the exit flag, so the mainloop can be restarted if desired
571 # Turn off the exit flag, so the mainloop can be restarted if desired
567 self.exit_now = False
572 self.exit_now = False
568
573
569 def raw_input(self, prompt=''):
574 def raw_input(self, prompt=''):
570 """Write a prompt and read a line.
575 """Write a prompt and read a line.
571
576
572 The returned line does not include the trailing newline.
577 The returned line does not include the trailing newline.
573 When the user enters the EOF key sequence, EOFError is raised.
578 When the user enters the EOF key sequence, EOFError is raised.
574
579
575 Parameters
580 Parameters
576 ----------
581 ----------
577
582
578 prompt : str, optional
583 prompt : str, optional
579 A string to be printed to prompt the user.
584 A string to be printed to prompt the user.
580 """
585 """
581 # raw_input expects str, but we pass it unicode sometimes
586 # raw_input expects str, but we pass it unicode sometimes
582 prompt = py3compat.cast_bytes_py2(prompt)
587 prompt = py3compat.cast_bytes_py2(prompt)
583
588
584 try:
589 try:
585 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
590 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
586 except ValueError:
591 except ValueError:
587 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
592 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
588 " or sys.stdout.close()!\nExiting IPython!\n")
593 " or sys.stdout.close()!\nExiting IPython!\n")
589 self.ask_exit()
594 self.ask_exit()
590 return ""
595 return ""
591
596
592 # Try to be reasonably smart about not re-indenting pasted input more
597 # Try to be reasonably smart about not re-indenting pasted input more
593 # than necessary. We do this by trimming out the auto-indent initial
598 # than necessary. We do this by trimming out the auto-indent initial
594 # spaces, if the user's actual input started itself with whitespace.
599 # spaces, if the user's actual input started itself with whitespace.
595 if self.autoindent:
600 if self.autoindent:
596 if num_ini_spaces(line) > self.indent_current_nsp:
601 if num_ini_spaces(line) > self.indent_current_nsp:
597 line = line[self.indent_current_nsp:]
602 line = line[self.indent_current_nsp:]
598 self.indent_current_nsp = 0
603 self.indent_current_nsp = 0
599
604
600 return line
605 return line
601
606
602 #-------------------------------------------------------------------------
607 #-------------------------------------------------------------------------
603 # Methods to support auto-editing of SyntaxErrors.
608 # Methods to support auto-editing of SyntaxErrors.
604 #-------------------------------------------------------------------------
609 #-------------------------------------------------------------------------
605
610
606 def edit_syntax_error(self):
611 def edit_syntax_error(self):
607 """The bottom half of the syntax error handler called in the main loop.
612 """The bottom half of the syntax error handler called in the main loop.
608
613
609 Loop until syntax error is fixed or user cancels.
614 Loop until syntax error is fixed or user cancels.
610 """
615 """
611
616
612 while self.SyntaxTB.last_syntax_error:
617 while self.SyntaxTB.last_syntax_error:
613 # copy and clear last_syntax_error
618 # copy and clear last_syntax_error
614 err = self.SyntaxTB.clear_err_state()
619 err = self.SyntaxTB.clear_err_state()
615 if not self._should_recompile(err):
620 if not self._should_recompile(err):
616 return
621 return
617 try:
622 try:
618 # may set last_syntax_error again if a SyntaxError is raised
623 # may set last_syntax_error again if a SyntaxError is raised
619 self.safe_execfile(err.filename,self.user_ns)
624 self.safe_execfile(err.filename,self.user_ns)
620 except:
625 except:
621 self.showtraceback()
626 self.showtraceback()
622 else:
627 else:
623 try:
628 try:
624 f = open(err.filename)
629 f = open(err.filename)
625 try:
630 try:
626 # This should be inside a display_trap block and I
631 # This should be inside a display_trap block and I
627 # think it is.
632 # think it is.
628 sys.displayhook(f.read())
633 sys.displayhook(f.read())
629 finally:
634 finally:
630 f.close()
635 f.close()
631 except:
636 except:
632 self.showtraceback()
637 self.showtraceback()
633
638
634 def _should_recompile(self,e):
639 def _should_recompile(self,e):
635 """Utility routine for edit_syntax_error"""
640 """Utility routine for edit_syntax_error"""
636
641
637 if e.filename in ('<ipython console>','<input>','<string>',
642 if e.filename in ('<ipython console>','<input>','<string>',
638 '<console>','<BackgroundJob compilation>',
643 '<console>','<BackgroundJob compilation>',
639 None):
644 None):
640
645
641 return False
646 return False
642 try:
647 try:
643 if (self.autoedit_syntax and
648 if (self.autoedit_syntax and
644 not self.ask_yes_no('Return to editor to correct syntax error? '
649 not self.ask_yes_no('Return to editor to correct syntax error? '
645 '[Y/n] ','y')):
650 '[Y/n] ','y')):
646 return False
651 return False
647 except EOFError:
652 except EOFError:
648 return False
653 return False
649
654
650 def int0(x):
655 def int0(x):
651 try:
656 try:
652 return int(x)
657 return int(x)
653 except TypeError:
658 except TypeError:
654 return 0
659 return 0
655 # always pass integer line and offset values to editor hook
660 # always pass integer line and offset values to editor hook
656 try:
661 try:
657 self.hooks.fix_error_editor(e.filename,
662 self.hooks.fix_error_editor(e.filename,
658 int0(e.lineno),int0(e.offset),e.msg)
663 int0(e.lineno),int0(e.offset),e.msg)
659 except TryNext:
664 except TryNext:
660 warn('Could not open editor')
665 warn('Could not open editor')
661 return False
666 return False
662 return True
667 return True
663
668
664 #-------------------------------------------------------------------------
669 #-------------------------------------------------------------------------
665 # Things related to exiting
670 # Things related to exiting
666 #-------------------------------------------------------------------------
671 #-------------------------------------------------------------------------
667
672
668 def ask_exit(self):
673 def ask_exit(self):
669 """ Ask the shell to exit. Can be overiden and used as a callback. """
674 """ Ask the shell to exit. Can be overiden and used as a callback. """
670 self.exit_now = True
675 self.exit_now = True
671
676
672 def exit(self):
677 def exit(self):
673 """Handle interactive exit.
678 """Handle interactive exit.
674
679
675 This method calls the ask_exit callback."""
680 This method calls the ask_exit callback."""
676 if self.confirm_exit:
681 if self.confirm_exit:
677 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
682 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
678 self.ask_exit()
683 self.ask_exit()
679 else:
684 else:
680 self.ask_exit()
685 self.ask_exit()
681
686
682 #-------------------------------------------------------------------------
687 #-------------------------------------------------------------------------
683 # Things related to magics
688 # Things related to magics
684 #-------------------------------------------------------------------------
689 #-------------------------------------------------------------------------
685
690
686 def init_magics(self):
691 def init_magics(self):
687 super(TerminalInteractiveShell, self).init_magics()
692 super(TerminalInteractiveShell, self).init_magics()
688 self.register_magics(TerminalMagics)
693 self.register_magics(TerminalMagics)
689
694
690 def showindentationerror(self):
695 def showindentationerror(self):
691 super(TerminalInteractiveShell, self).showindentationerror()
696 super(TerminalInteractiveShell, self).showindentationerror()
692 if not self.using_paste_magics:
697 if not self.using_paste_magics:
693 print("If you want to paste code into IPython, try the "
698 print("If you want to paste code into IPython, try the "
694 "%paste and %cpaste magic functions.")
699 "%paste and %cpaste magic functions.")
695
700
696
701
697 InteractiveShellABC.register(TerminalInteractiveShell)
702 InteractiveShellABC.register(TerminalInteractiveShell)
@@ -1,203 +1,295 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the key interactiveshell module.
2 """Tests for the key interactiveshell module.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Julian Taylor
6 * Julian Taylor
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2011 The IPython Development Team
9 # Copyright (C) 2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # stdlib
18 # stdlib
19 import sys
19 import sys
20 import types
20 import unittest
21 import unittest
21
22
23 from IPython.core.inputtransformer import InputTransformer
22 from IPython.testing.decorators import skipif
24 from IPython.testing.decorators import skipif
23 from IPython.utils import py3compat
25 from IPython.utils import py3compat
24 from IPython.testing import tools as tt
26 from IPython.testing import tools as tt
25
27
28 # Decorator for interaction loop tests -----------------------------------------
29
30 class mock_input_helper(object):
31 """Machinery for tests of the main interact loop.
32
33 Used by the mock_input decorator.
34 """
35 def __init__(self, testgen):
36 self.testgen = testgen
37 self.exception = None
38 self.ip = get_ipython()
39
40 def __enter__(self):
41 self.orig_raw_input = self.ip.raw_input
42 self.ip.raw_input = self.fake_input
43 return self
44
45 def __exit__(self, etype, value, tb):
46 self.ip.raw_input = self.orig_raw_input
47
48 def fake_input(self, prompt):
49 try:
50 return next(self.testgen)
51 except StopIteration:
52 self.ip.exit_now = True
53 return u''
54 except:
55 self.exception = sys.exc_info()
56 self.ip.exit_now = True
57 return u''
58
59 def mock_input(testfunc):
60 """Decorator for tests of the main interact loop.
61
62 Write the test as a generator, yield-ing the input strings, which IPython
63 will see as if they were typed in at the prompt.
64 """
65 def test_method(self):
66 testgen = testfunc(self)
67 with mock_input_helper(testgen) as mih:
68 mih.ip.interact(display_banner=False)
69
70 if mih.exception is not None:
71 # Re-raise captured exception
72 etype, value, tb = mih.exception
73 import traceback
74 traceback.print_tb(tb, file=sys.stdout)
75 del tb # Avoid reference loop
76 raise value
77
78 return test_method
79
80 # Test classes -----------------------------------------------------------------
81
26 class InteractiveShellTestCase(unittest.TestCase):
82 class InteractiveShellTestCase(unittest.TestCase):
27 def rl_hist_entries(self, rl, n):
83 def rl_hist_entries(self, rl, n):
28 """Get last n readline history entries as a list"""
84 """Get last n readline history entries as a list"""
29 return [rl.get_history_item(rl.get_current_history_length() - x)
85 return [rl.get_history_item(rl.get_current_history_length() - x)
30 for x in range(n - 1, -1, -1)]
86 for x in range(n - 1, -1, -1)]
31
87
32 def test_runs_without_rl(self):
88 def test_runs_without_rl(self):
33 """Test that function does not throw without readline"""
89 """Test that function does not throw without readline"""
34 ip = get_ipython()
90 ip = get_ipython()
35 ip.has_readline = False
91 ip.has_readline = False
36 ip.readline = None
92 ip.readline = None
37 ip._replace_rlhist_multiline(u'source', 0)
93 ip._replace_rlhist_multiline(u'source', 0)
38
94
39 @skipif(not get_ipython().has_readline, 'no readline')
95 @skipif(not get_ipython().has_readline, 'no readline')
40 def test_runs_without_remove_history_item(self):
96 def test_runs_without_remove_history_item(self):
41 """Test that function does not throw on windows without
97 """Test that function does not throw on windows without
42 remove_history_item"""
98 remove_history_item"""
43 ip = get_ipython()
99 ip = get_ipython()
44 if hasattr(ip.readline, 'remove_history_item'):
100 if hasattr(ip.readline, 'remove_history_item'):
45 del ip.readline.remove_history_item
101 del ip.readline.remove_history_item
46 ip._replace_rlhist_multiline(u'source', 0)
102 ip._replace_rlhist_multiline(u'source', 0)
47
103
48 @skipif(not get_ipython().has_readline, 'no readline')
104 @skipif(not get_ipython().has_readline, 'no readline')
49 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
105 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
50 'no remove_history_item')
106 'no remove_history_item')
51 def test_replace_multiline_hist_disabled(self):
107 def test_replace_multiline_hist_disabled(self):
52 """Test that multiline replace does nothing if disabled"""
108 """Test that multiline replace does nothing if disabled"""
53 ip = get_ipython()
109 ip = get_ipython()
54 ip.multiline_history = False
110 ip.multiline_history = False
55
111
56 ghist = [u'line1', u'line2']
112 ghist = [u'line1', u'line2']
57 for h in ghist:
113 for h in ghist:
58 ip.readline.add_history(h)
114 ip.readline.add_history(h)
59 hlen_b4_cell = ip.readline.get_current_history_length()
115 hlen_b4_cell = ip.readline.get_current_history_length()
60 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€\nsource2',
116 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€\nsource2',
61 hlen_b4_cell)
117 hlen_b4_cell)
62
118
63 self.assertEqual(ip.readline.get_current_history_length(),
119 self.assertEqual(ip.readline.get_current_history_length(),
64 hlen_b4_cell)
120 hlen_b4_cell)
65 hist = self.rl_hist_entries(ip.readline, 2)
121 hist = self.rl_hist_entries(ip.readline, 2)
66 self.assertEqual(hist, ghist)
122 self.assertEqual(hist, ghist)
67
123
68 @skipif(not get_ipython().has_readline, 'no readline')
124 @skipif(not get_ipython().has_readline, 'no readline')
69 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
125 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
70 'no remove_history_item')
126 'no remove_history_item')
71 def test_replace_multiline_hist_adds(self):
127 def test_replace_multiline_hist_adds(self):
72 """Test that multiline replace function adds history"""
128 """Test that multiline replace function adds history"""
73 ip = get_ipython()
129 ip = get_ipython()
74
130
75 hlen_b4_cell = ip.readline.get_current_history_length()
131 hlen_b4_cell = ip.readline.get_current_history_length()
76 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€', hlen_b4_cell)
132 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€', hlen_b4_cell)
77
133
78 self.assertEqual(hlen_b4_cell,
134 self.assertEqual(hlen_b4_cell,
79 ip.readline.get_current_history_length())
135 ip.readline.get_current_history_length())
80
136
81 @skipif(not get_ipython().has_readline, 'no readline')
137 @skipif(not get_ipython().has_readline, 'no readline')
82 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
138 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
83 'no remove_history_item')
139 'no remove_history_item')
84 def test_replace_multiline_hist_keeps_history(self):
140 def test_replace_multiline_hist_keeps_history(self):
85 """Test that multiline replace does not delete history"""
141 """Test that multiline replace does not delete history"""
86 ip = get_ipython()
142 ip = get_ipython()
87 ip.multiline_history = True
143 ip.multiline_history = True
88
144
89 ghist = [u'line1', u'line2']
145 ghist = [u'line1', u'line2']
90 for h in ghist:
146 for h in ghist:
91 ip.readline.add_history(h)
147 ip.readline.add_history(h)
92
148
93 #start cell
149 #start cell
94 hlen_b4_cell = ip.readline.get_current_history_length()
150 hlen_b4_cell = ip.readline.get_current_history_length()
95 # nothing added to rl history, should do nothing
151 # nothing added to rl history, should do nothing
96 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€\nsource2',
152 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€\nsource2',
97 hlen_b4_cell)
153 hlen_b4_cell)
98
154
99 self.assertEqual(ip.readline.get_current_history_length(),
155 self.assertEqual(ip.readline.get_current_history_length(),
100 hlen_b4_cell)
156 hlen_b4_cell)
101 hist = self.rl_hist_entries(ip.readline, 2)
157 hist = self.rl_hist_entries(ip.readline, 2)
102 self.assertEqual(hist, ghist)
158 self.assertEqual(hist, ghist)
103
159
104
160
105 @skipif(not get_ipython().has_readline, 'no readline')
161 @skipif(not get_ipython().has_readline, 'no readline')
106 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
162 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
107 'no remove_history_item')
163 'no remove_history_item')
108 def test_replace_multiline_hist_replaces_twice(self):
164 def test_replace_multiline_hist_replaces_twice(self):
109 """Test that multiline entries are replaced twice"""
165 """Test that multiline entries are replaced twice"""
110 ip = get_ipython()
166 ip = get_ipython()
111 ip.multiline_history = True
167 ip.multiline_history = True
112
168
113 ip.readline.add_history(u'line0')
169 ip.readline.add_history(u'line0')
114 #start cell
170 #start cell
115 hlen_b4_cell = ip.readline.get_current_history_length()
171 hlen_b4_cell = ip.readline.get_current_history_length()
116 ip.readline.add_history('l€ne1')
172 ip.readline.add_history('l€ne1')
117 ip.readline.add_history('line2')
173 ip.readline.add_history('line2')
118 #replace cell with single line
174 #replace cell with single line
119 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne1\nline2',
175 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne1\nline2',
120 hlen_b4_cell)
176 hlen_b4_cell)
121 ip.readline.add_history('l€ne3')
177 ip.readline.add_history('l€ne3')
122 ip.readline.add_history('line4')
178 ip.readline.add_history('line4')
123 #replace cell with single line
179 #replace cell with single line
124 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne3\nline4',
180 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne3\nline4',
125 hlen_b4_cell)
181 hlen_b4_cell)
126
182
127 self.assertEqual(ip.readline.get_current_history_length(),
183 self.assertEqual(ip.readline.get_current_history_length(),
128 hlen_b4_cell)
184 hlen_b4_cell)
129 hist = self.rl_hist_entries(ip.readline, 3)
185 hist = self.rl_hist_entries(ip.readline, 3)
130 expected = [u'line0', u'l€ne1\nline2', u'l€ne3\nline4']
186 expected = [u'line0', u'l€ne1\nline2', u'l€ne3\nline4']
131 # perform encoding, in case of casting due to ASCII locale
187 # perform encoding, in case of casting due to ASCII locale
132 enc = sys.stdin.encoding or "utf-8"
188 enc = sys.stdin.encoding or "utf-8"
133 expected = [ py3compat.unicode_to_str(e, enc) for e in expected ]
189 expected = [ py3compat.unicode_to_str(e, enc) for e in expected ]
134 self.assertEqual(hist, expected)
190 self.assertEqual(hist, expected)
135
191
136
192
137 @skipif(not get_ipython().has_readline, 'no readline')
193 @skipif(not get_ipython().has_readline, 'no readline')
138 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
194 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
139 'no remove_history_item')
195 'no remove_history_item')
140 def test_replace_multiline_hist_replaces_empty_line(self):
196 def test_replace_multiline_hist_replaces_empty_line(self):
141 """Test that multiline history skips empty line cells"""
197 """Test that multiline history skips empty line cells"""
142 ip = get_ipython()
198 ip = get_ipython()
143 ip.multiline_history = True
199 ip.multiline_history = True
144
200
145 ip.readline.add_history(u'line0')
201 ip.readline.add_history(u'line0')
146 #start cell
202 #start cell
147 hlen_b4_cell = ip.readline.get_current_history_length()
203 hlen_b4_cell = ip.readline.get_current_history_length()
148 ip.readline.add_history('l€ne1')
204 ip.readline.add_history('l€ne1')
149 ip.readline.add_history('line2')
205 ip.readline.add_history('line2')
150 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne1\nline2',
206 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne1\nline2',
151 hlen_b4_cell)
207 hlen_b4_cell)
152 ip.readline.add_history('')
208 ip.readline.add_history('')
153 hlen_b4_cell = ip._replace_rlhist_multiline(u'', hlen_b4_cell)
209 hlen_b4_cell = ip._replace_rlhist_multiline(u'', hlen_b4_cell)
154 ip.readline.add_history('l€ne3')
210 ip.readline.add_history('l€ne3')
155 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne3', hlen_b4_cell)
211 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne3', hlen_b4_cell)
156 ip.readline.add_history(' ')
212 ip.readline.add_history(' ')
157 hlen_b4_cell = ip._replace_rlhist_multiline(' ', hlen_b4_cell)
213 hlen_b4_cell = ip._replace_rlhist_multiline(' ', hlen_b4_cell)
158 ip.readline.add_history('\t')
214 ip.readline.add_history('\t')
159 ip.readline.add_history('\t ')
215 ip.readline.add_history('\t ')
160 hlen_b4_cell = ip._replace_rlhist_multiline('\t', hlen_b4_cell)
216 hlen_b4_cell = ip._replace_rlhist_multiline('\t', hlen_b4_cell)
161 ip.readline.add_history('line4')
217 ip.readline.add_history('line4')
162 hlen_b4_cell = ip._replace_rlhist_multiline(u'line4', hlen_b4_cell)
218 hlen_b4_cell = ip._replace_rlhist_multiline(u'line4', hlen_b4_cell)
163
219
164 self.assertEqual(ip.readline.get_current_history_length(),
220 self.assertEqual(ip.readline.get_current_history_length(),
165 hlen_b4_cell)
221 hlen_b4_cell)
166 hist = self.rl_hist_entries(ip.readline, 4)
222 hist = self.rl_hist_entries(ip.readline, 4)
167 # expect no empty cells in history
223 # expect no empty cells in history
168 expected = [u'line0', u'l€ne1\nline2', u'l€ne3', u'line4']
224 expected = [u'line0', u'l€ne1\nline2', u'l€ne3', u'line4']
169 # perform encoding, in case of casting due to ASCII locale
225 # perform encoding, in case of casting due to ASCII locale
170 enc = sys.stdin.encoding or "utf-8"
226 enc = sys.stdin.encoding or "utf-8"
171 expected = [ py3compat.unicode_to_str(e, enc) for e in expected ]
227 expected = [ py3compat.unicode_to_str(e, enc) for e in expected ]
172 self.assertEqual(hist, expected)
228 self.assertEqual(hist, expected)
173
229
230 @mock_input
231 def test_inputtransformer_syntaxerror(self):
232 ip = get_ipython()
233 transformer = SyntaxErrorTransformer()
234 ip.input_splitter.python_line_transforms.append(transformer)
235 ip.input_transformer_manager.python_line_transforms.append(transformer)
236
237 try:
238 #raise Exception
239 with tt.AssertPrints('4', suppress=False):
240 yield u'print(2*2)'
241
242 with tt.AssertPrints('SyntaxError: input contains', suppress=False):
243 yield u'print(2345) # syntaxerror'
244
245 with tt.AssertPrints('16', suppress=False):
246 yield u'print(4*4)'
247
248 finally:
249 ip.input_splitter.python_line_transforms.remove(transformer)
250 ip.input_transformer_manager.python_line_transforms.remove(transformer)
251
252
253 class SyntaxErrorTransformer(InputTransformer):
254 def push(self, line):
255 pos = line.find('syntaxerror')
256 if pos >= 0:
257 e = SyntaxError('input contains "syntaxerror"')
258 e.text = line
259 e.offset = pos + 1
260 raise e
261 return line
262
263 def reset(self):
264 pass
265
174 class TerminalMagicsTestCase(unittest.TestCase):
266 class TerminalMagicsTestCase(unittest.TestCase):
175 def test_paste_magics_message(self):
267 def test_paste_magics_message(self):
176 """Test that an IndentationError while using paste magics doesn't
268 """Test that an IndentationError while using paste magics doesn't
177 trigger a message about paste magics and also the opposite."""
269 trigger a message about paste magics and also the opposite."""
178
270
179 ip = get_ipython()
271 ip = get_ipython()
180 s = ('for a in range(5):\n'
272 s = ('for a in range(5):\n'
181 'print(a)')
273 'print(a)')
182
274
183 tm = ip.magics_manager.registry['TerminalMagics']
275 tm = ip.magics_manager.registry['TerminalMagics']
184 with tt.AssertPrints("If you want to paste code into IPython, try the "
276 with tt.AssertPrints("If you want to paste code into IPython, try the "
185 "%paste and %cpaste magic functions."):
277 "%paste and %cpaste magic functions."):
186 ip.run_cell(s)
278 ip.run_cell(s)
187
279
188 with tt.AssertNotPrints("If you want to paste code into IPython, try the "
280 with tt.AssertNotPrints("If you want to paste code into IPython, try the "
189 "%paste and %cpaste magic functions."):
281 "%paste and %cpaste magic functions."):
190 tm.store_or_execute(s, name=None)
282 tm.store_or_execute(s, name=None)
191
283
192 def test_paste_magics_blankline(self):
284 def test_paste_magics_blankline(self):
193 """Test that code with a blank line doesn't get split (gh-3246)."""
285 """Test that code with a blank line doesn't get split (gh-3246)."""
194 ip = get_ipython()
286 ip = get_ipython()
195 s = ('def pasted_func(a):\n'
287 s = ('def pasted_func(a):\n'
196 ' b = a+1\n'
288 ' b = a+1\n'
197 '\n'
289 '\n'
198 ' return b')
290 ' return b')
199
291
200 tm = ip.magics_manager.registry['TerminalMagics']
292 tm = ip.magics_manager.registry['TerminalMagics']
201 tm.store_or_execute(s, name=None)
293 tm.store_or_execute(s, name=None)
202
294
203 self.assertEqual(ip.user_ns['pasted_func'](54), 55)
295 self.assertEqual(ip.user_ns['pasted_func'](54), 55)
@@ -1,257 +1,262 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-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 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 from __future__ import print_function
13 from __future__ import absolute_import
13 from __future__ import absolute_import
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 import codecs
18 import codecs
19 import os
19 import os
20 import sys
20 import sys
21 import tempfile
21 import tempfile
22 from .capture import CapturedIO, capture_output
22 from .capture import CapturedIO, capture_output
23 from .py3compat import string_types, input, PY3
23 from .py3compat import string_types, input, PY3
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Code
26 # Code
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29
29
30 class IOStream:
30 class IOStream:
31
31
32 def __init__(self,stream, fallback=None):
32 def __init__(self,stream, fallback=None):
33 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
33 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
34 if fallback is not None:
34 if fallback is not None:
35 stream = fallback
35 stream = fallback
36 else:
36 else:
37 raise ValueError("fallback required, but not specified")
37 raise ValueError("fallback required, but not specified")
38 self.stream = stream
38 self.stream = stream
39 self._swrite = stream.write
39 self._swrite = stream.write
40
40
41 # clone all methods not overridden:
41 # clone all methods not overridden:
42 def clone(meth):
42 def clone(meth):
43 return not hasattr(self, meth) and not meth.startswith('_')
43 return not hasattr(self, meth) and not meth.startswith('_')
44 for meth in filter(clone, dir(stream)):
44 for meth in filter(clone, dir(stream)):
45 setattr(self, meth, getattr(stream, meth))
45 setattr(self, meth, getattr(stream, meth))
46
46
47 def __repr__(self):
48 cls = self.__class__
49 tpl = '{mod}.{cls}({args})'
50 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
51
47 def write(self,data):
52 def write(self,data):
48 try:
53 try:
49 self._swrite(data)
54 self._swrite(data)
50 except:
55 except:
51 try:
56 try:
52 # print handles some unicode issues which may trip a plain
57 # print handles some unicode issues which may trip a plain
53 # write() call. Emulate write() by using an empty end
58 # write() call. Emulate write() by using an empty end
54 # argument.
59 # argument.
55 print(data, end='', file=self.stream)
60 print(data, end='', file=self.stream)
56 except:
61 except:
57 # if we get here, something is seriously broken.
62 # if we get here, something is seriously broken.
58 print('ERROR - failed to write data to stream:', self.stream,
63 print('ERROR - failed to write data to stream:', self.stream,
59 file=sys.stderr)
64 file=sys.stderr)
60
65
61 def writelines(self, lines):
66 def writelines(self, lines):
62 if isinstance(lines, string_types):
67 if isinstance(lines, string_types):
63 lines = [lines]
68 lines = [lines]
64 for line in lines:
69 for line in lines:
65 self.write(line)
70 self.write(line)
66
71
67 # This class used to have a writeln method, but regular files and streams
72 # This class used to have a writeln method, but regular files and streams
68 # in Python don't have this method. We need to keep this completely
73 # in Python don't have this method. We need to keep this completely
69 # compatible so we removed it.
74 # compatible so we removed it.
70
75
71 @property
76 @property
72 def closed(self):
77 def closed(self):
73 return self.stream.closed
78 return self.stream.closed
74
79
75 def close(self):
80 def close(self):
76 pass
81 pass
77
82
78 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
83 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
79 devnull = open(os.devnull, 'a')
84 devnull = open(os.devnull, 'a')
80 stdin = IOStream(sys.stdin, fallback=devnull)
85 stdin = IOStream(sys.stdin, fallback=devnull)
81 stdout = IOStream(sys.stdout, fallback=devnull)
86 stdout = IOStream(sys.stdout, fallback=devnull)
82 stderr = IOStream(sys.stderr, fallback=devnull)
87 stderr = IOStream(sys.stderr, fallback=devnull)
83
88
84 class IOTerm:
89 class IOTerm:
85 """ Term holds the file or file-like objects for handling I/O operations.
90 """ Term holds the file or file-like objects for handling I/O operations.
86
91
87 These are normally just sys.stdin, sys.stdout and sys.stderr but for
92 These are normally just sys.stdin, sys.stdout and sys.stderr but for
88 Windows they can can replaced to allow editing the strings before they are
93 Windows they can can replaced to allow editing the strings before they are
89 displayed."""
94 displayed."""
90
95
91 # In the future, having IPython channel all its I/O operations through
96 # In the future, having IPython channel all its I/O operations through
92 # this class will make it easier to embed it into other environments which
97 # this class will make it easier to embed it into other environments which
93 # are not a normal terminal (such as a GUI-based shell)
98 # are not a normal terminal (such as a GUI-based shell)
94 def __init__(self, stdin=None, stdout=None, stderr=None):
99 def __init__(self, stdin=None, stdout=None, stderr=None):
95 mymodule = sys.modules[__name__]
100 mymodule = sys.modules[__name__]
96 self.stdin = IOStream(stdin, mymodule.stdin)
101 self.stdin = IOStream(stdin, mymodule.stdin)
97 self.stdout = IOStream(stdout, mymodule.stdout)
102 self.stdout = IOStream(stdout, mymodule.stdout)
98 self.stderr = IOStream(stderr, mymodule.stderr)
103 self.stderr = IOStream(stderr, mymodule.stderr)
99
104
100
105
101 class Tee(object):
106 class Tee(object):
102 """A class to duplicate an output stream to stdout/err.
107 """A class to duplicate an output stream to stdout/err.
103
108
104 This works in a manner very similar to the Unix 'tee' command.
109 This works in a manner very similar to the Unix 'tee' command.
105
110
106 When the object is closed or deleted, it closes the original file given to
111 When the object is closed or deleted, it closes the original file given to
107 it for duplication.
112 it for duplication.
108 """
113 """
109 # Inspired by:
114 # Inspired by:
110 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
115 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
111
116
112 def __init__(self, file_or_name, mode="w", channel='stdout'):
117 def __init__(self, file_or_name, mode="w", channel='stdout'):
113 """Construct a new Tee object.
118 """Construct a new Tee object.
114
119
115 Parameters
120 Parameters
116 ----------
121 ----------
117 file_or_name : filename or open filehandle (writable)
122 file_or_name : filename or open filehandle (writable)
118 File that will be duplicated
123 File that will be duplicated
119
124
120 mode : optional, valid mode for open().
125 mode : optional, valid mode for open().
121 If a filename was give, open with this mode.
126 If a filename was give, open with this mode.
122
127
123 channel : str, one of ['stdout', 'stderr']
128 channel : str, one of ['stdout', 'stderr']
124 """
129 """
125 if channel not in ['stdout', 'stderr']:
130 if channel not in ['stdout', 'stderr']:
126 raise ValueError('Invalid channel spec %s' % channel)
131 raise ValueError('Invalid channel spec %s' % channel)
127
132
128 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
133 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
129 self.file = file_or_name
134 self.file = file_or_name
130 else:
135 else:
131 self.file = open(file_or_name, mode)
136 self.file = open(file_or_name, mode)
132 self.channel = channel
137 self.channel = channel
133 self.ostream = getattr(sys, channel)
138 self.ostream = getattr(sys, channel)
134 setattr(sys, channel, self)
139 setattr(sys, channel, self)
135 self._closed = False
140 self._closed = False
136
141
137 def close(self):
142 def close(self):
138 """Close the file and restore the channel."""
143 """Close the file and restore the channel."""
139 self.flush()
144 self.flush()
140 setattr(sys, self.channel, self.ostream)
145 setattr(sys, self.channel, self.ostream)
141 self.file.close()
146 self.file.close()
142 self._closed = True
147 self._closed = True
143
148
144 def write(self, data):
149 def write(self, data):
145 """Write data to both channels."""
150 """Write data to both channels."""
146 self.file.write(data)
151 self.file.write(data)
147 self.ostream.write(data)
152 self.ostream.write(data)
148 self.ostream.flush()
153 self.ostream.flush()
149
154
150 def flush(self):
155 def flush(self):
151 """Flush both channels."""
156 """Flush both channels."""
152 self.file.flush()
157 self.file.flush()
153 self.ostream.flush()
158 self.ostream.flush()
154
159
155 def __del__(self):
160 def __del__(self):
156 if not self._closed:
161 if not self._closed:
157 self.close()
162 self.close()
158
163
159
164
160 def ask_yes_no(prompt, default=None, interrupt=None):
165 def ask_yes_no(prompt, default=None, interrupt=None):
161 """Asks a question and returns a boolean (y/n) answer.
166 """Asks a question and returns a boolean (y/n) answer.
162
167
163 If default is given (one of 'y','n'), it is used if the user input is
168 If default is given (one of 'y','n'), it is used if the user input is
164 empty. If interrupt is given (one of 'y','n'), it is used if the user
169 empty. If interrupt is given (one of 'y','n'), it is used if the user
165 presses Ctrl-C. Otherwise the question is repeated until an answer is
170 presses Ctrl-C. Otherwise the question is repeated until an answer is
166 given.
171 given.
167
172
168 An EOF is treated as the default answer. If there is no default, an
173 An EOF is treated as the default answer. If there is no default, an
169 exception is raised to prevent infinite loops.
174 exception is raised to prevent infinite loops.
170
175
171 Valid answers are: y/yes/n/no (match is not case sensitive)."""
176 Valid answers are: y/yes/n/no (match is not case sensitive)."""
172
177
173 answers = {'y':True,'n':False,'yes':True,'no':False}
178 answers = {'y':True,'n':False,'yes':True,'no':False}
174 ans = None
179 ans = None
175 while ans not in answers.keys():
180 while ans not in answers.keys():
176 try:
181 try:
177 ans = input(prompt+' ').lower()
182 ans = input(prompt+' ').lower()
178 if not ans: # response was an empty string
183 if not ans: # response was an empty string
179 ans = default
184 ans = default
180 except KeyboardInterrupt:
185 except KeyboardInterrupt:
181 if interrupt:
186 if interrupt:
182 ans = interrupt
187 ans = interrupt
183 except EOFError:
188 except EOFError:
184 if default in answers.keys():
189 if default in answers.keys():
185 ans = default
190 ans = default
186 print()
191 print()
187 else:
192 else:
188 raise
193 raise
189
194
190 return answers[ans]
195 return answers[ans]
191
196
192
197
193 def temp_pyfile(src, ext='.py'):
198 def temp_pyfile(src, ext='.py'):
194 """Make a temporary python file, return filename and filehandle.
199 """Make a temporary python file, return filename and filehandle.
195
200
196 Parameters
201 Parameters
197 ----------
202 ----------
198 src : string or list of strings (no need for ending newlines if list)
203 src : string or list of strings (no need for ending newlines if list)
199 Source code to be written to the file.
204 Source code to be written to the file.
200
205
201 ext : optional, string
206 ext : optional, string
202 Extension for the generated file.
207 Extension for the generated file.
203
208
204 Returns
209 Returns
205 -------
210 -------
206 (filename, open filehandle)
211 (filename, open filehandle)
207 It is the caller's responsibility to close the open file and unlink it.
212 It is the caller's responsibility to close the open file and unlink it.
208 """
213 """
209 fname = tempfile.mkstemp(ext)[1]
214 fname = tempfile.mkstemp(ext)[1]
210 f = open(fname,'w')
215 f = open(fname,'w')
211 f.write(src)
216 f.write(src)
212 f.flush()
217 f.flush()
213 return fname, f
218 return fname, f
214
219
215
220
216 def raw_print(*args, **kw):
221 def raw_print(*args, **kw):
217 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
222 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
218
223
219 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
224 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
220 file=sys.__stdout__)
225 file=sys.__stdout__)
221 sys.__stdout__.flush()
226 sys.__stdout__.flush()
222
227
223
228
224 def raw_print_err(*args, **kw):
229 def raw_print_err(*args, **kw):
225 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
230 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
226
231
227 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
232 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
228 file=sys.__stderr__)
233 file=sys.__stderr__)
229 sys.__stderr__.flush()
234 sys.__stderr__.flush()
230
235
231
236
232 # Short aliases for quick debugging, do NOT use these in production code.
237 # Short aliases for quick debugging, do NOT use these in production code.
233 rprint = raw_print
238 rprint = raw_print
234 rprinte = raw_print_err
239 rprinte = raw_print_err
235
240
236 def unicode_std_stream(stream='stdout'):
241 def unicode_std_stream(stream='stdout'):
237 u"""Get a wrapper to write unicode to stdout/stderr as UTF-8.
242 u"""Get a wrapper to write unicode to stdout/stderr as UTF-8.
238
243
239 This ignores environment variables and default encodings, to reliably write
244 This ignores environment variables and default encodings, to reliably write
240 unicode to stdout or stderr.
245 unicode to stdout or stderr.
241
246
242 ::
247 ::
243
248
244 unicode_std_stream().write(u'Ε‚@e¢ŧ←')
249 unicode_std_stream().write(u'Ε‚@e¢ŧ←')
245 """
250 """
246 assert stream in ('stdout', 'stderr')
251 assert stream in ('stdout', 'stderr')
247 stream = getattr(sys, stream)
252 stream = getattr(sys, stream)
248 if PY3:
253 if PY3:
249 try:
254 try:
250 stream_b = stream.buffer
255 stream_b = stream.buffer
251 except AttributeError:
256 except AttributeError:
252 # sys.stdout has been replaced - use it directly
257 # sys.stdout has been replaced - use it directly
253 return stream
258 return stream
254 else:
259 else:
255 stream_b = stream
260 stream_b = stream
256
261
257 return codecs.getwriter('utf-8')(stream_b)
262 return codecs.getwriter('utf-8')(stream_b)
@@ -1,132 +1,140 b''
1
1
2 ===========================
2 ===========================
3 Custom input transformation
3 Custom input transformation
4 ===========================
4 ===========================
5
5
6 IPython extends Python syntax to allow things like magic commands, and help with
6 IPython extends Python syntax to allow things like magic commands, and help with
7 the ``?`` syntax. There are several ways to customise how the user's input is
7 the ``?`` syntax. There are several ways to customise how the user's input is
8 processed into Python code to be executed.
8 processed into Python code to be executed.
9
9
10 These hooks are mainly for other projects using IPython as the core of their
10 These hooks are mainly for other projects using IPython as the core of their
11 interactive interface. Using them carelessly can easily break IPython!
11 interactive interface. Using them carelessly can easily break IPython!
12
12
13 String based transformations
13 String based transformations
14 ============================
14 ============================
15
15
16 .. currentmodule:: IPython.core.inputtransforms
16 .. currentmodule:: IPython.core.inputtransforms
17
17
18 When the user enters a line of code, it is first processed as a string. By the
18 When the user enters a line of code, it is first processed as a string. By the
19 end of this stage, it must be valid Python syntax.
19 end of this stage, it must be valid Python syntax.
20
20
21 These transformers all subclass :class:`IPython.core.inputtransformer.InputTransformer`,
21 These transformers all subclass :class:`IPython.core.inputtransformer.InputTransformer`,
22 and are used by :class:`IPython.core.inputsplitter.IPythonInputSplitter`.
22 and are used by :class:`IPython.core.inputsplitter.IPythonInputSplitter`.
23
23
24 These transformers act in three groups, stored separately as lists of instances
24 These transformers act in three groups, stored separately as lists of instances
25 in attributes of :class:`~IPython.core.inputsplitter.IPythonInputSplitter`:
25 in attributes of :class:`~IPython.core.inputsplitter.IPythonInputSplitter`:
26
26
27 * ``physical_line_transforms`` act on the lines as the user enters them. For
27 * ``physical_line_transforms`` act on the lines as the user enters them. For
28 example, these strip Python prompts from examples pasted in.
28 example, these strip Python prompts from examples pasted in.
29 * ``logical_line_transforms`` act on lines as connected by explicit line
29 * ``logical_line_transforms`` act on lines as connected by explicit line
30 continuations, i.e. ``\`` at the end of physical lines. They are skipped
30 continuations, i.e. ``\`` at the end of physical lines. They are skipped
31 inside multiline Python statements. This is the point where IPython recognises
31 inside multiline Python statements. This is the point where IPython recognises
32 ``%magic`` commands, for instance.
32 ``%magic`` commands, for instance.
33 * ``python_line_transforms`` act on blocks containing complete Python statements.
33 * ``python_line_transforms`` act on blocks containing complete Python statements.
34 Multi-line strings, lists and function calls are reassembled before being
34 Multi-line strings, lists and function calls are reassembled before being
35 passed to these, but note that function and class *definitions* are still a
35 passed to these, but note that function and class *definitions* are still a
36 series of separate statements. IPython does not use any of these by default.
36 series of separate statements. IPython does not use any of these by default.
37
37
38 An InteractiveShell instance actually has two
38 An InteractiveShell instance actually has two
39 :class:`~IPython.core.inputsplitter.IPythonInputSplitter` instances, as the
39 :class:`~IPython.core.inputsplitter.IPythonInputSplitter` instances, as the
40 attributes :attr:`~IPython.core.interactiveshell.InteractiveShell.input_splitter`,
40 attributes :attr:`~IPython.core.interactiveshell.InteractiveShell.input_splitter`,
41 to tell when a block of input is complete, and
41 to tell when a block of input is complete, and
42 :attr:`~IPython.core.interactiveshell.InteractiveShell.input_transformer_manager`,
42 :attr:`~IPython.core.interactiveshell.InteractiveShell.input_transformer_manager`,
43 to transform complete cells. If you add a transformer, you should make sure that
43 to transform complete cells. If you add a transformer, you should make sure that
44 it gets added to both, e.g.::
44 it gets added to both, e.g.::
45
45
46 ip.input_splitter.logical_line_transforms.append(my_transformer())
46 ip.input_splitter.logical_line_transforms.append(my_transformer())
47 ip.input_transformer_manager.logical_line_transforms.append(my_transformer())
47 ip.input_transformer_manager.logical_line_transforms.append(my_transformer())
48
48
49 These transformers may raise :exc:`SyntaxError` if the input code is invalid, but
50 in most cases it is clearer to pass unrecognised code through unmodified and let
51 Python's own parser decide whether it is valid.
52
53 .. versionchanged:: 2.0
54
55 Added the option to raise :exc:`SyntaxError`.
56
49 Stateless transformations
57 Stateless transformations
50 -------------------------
58 -------------------------
51
59
52 The simplest kind of transformations work one line at a time. Write a function
60 The simplest kind of transformations work one line at a time. Write a function
53 which takes a line and returns a line, and decorate it with
61 which takes a line and returns a line, and decorate it with
54 :meth:`StatelessInputTransformer.wrap`::
62 :meth:`StatelessInputTransformer.wrap`::
55
63
56 @StatelessInputTransformer.wrap
64 @StatelessInputTransformer.wrap
57 def my_special_commands(line):
65 def my_special_commands(line):
58 if line.startswith("Β¬"):
66 if line.startswith("Β¬"):
59 return "specialcommand(" + repr(line) + ")"
67 return "specialcommand(" + repr(line) + ")"
60 return line
68 return line
61
69
62 The decorator returns a factory function which will produce instances of
70 The decorator returns a factory function which will produce instances of
63 :class:`~IPython.core.inputtransformer.StatelessInputTransformer` using your
71 :class:`~IPython.core.inputtransformer.StatelessInputTransformer` using your
64 function.
72 function.
65
73
66 Coroutine transformers
74 Coroutine transformers
67 ----------------------
75 ----------------------
68
76
69 More advanced transformers can be written as coroutines. The coroutine will be
77 More advanced transformers can be written as coroutines. The coroutine will be
70 sent each line in turn, followed by ``None`` to reset it. It can yield lines, or
78 sent each line in turn, followed by ``None`` to reset it. It can yield lines, or
71 ``None`` if it is accumulating text to yield at a later point. When reset, it
79 ``None`` if it is accumulating text to yield at a later point. When reset, it
72 should give up any code it has accumulated.
80 should give up any code it has accumulated.
73
81
74 This code in IPython strips a constant amount of leading indentation from each
82 This code in IPython strips a constant amount of leading indentation from each
75 line in a cell::
83 line in a cell::
76
84
77 @CoroutineInputTransformer.wrap
85 @CoroutineInputTransformer.wrap
78 def leading_indent():
86 def leading_indent():
79 """Remove leading indentation.
87 """Remove leading indentation.
80
88
81 If the first line starts with a spaces or tabs, the same whitespace will be
89 If the first line starts with a spaces or tabs, the same whitespace will be
82 removed from each following line until it is reset.
90 removed from each following line until it is reset.
83 """
91 """
84 space_re = re.compile(r'^[ \t]+')
92 space_re = re.compile(r'^[ \t]+')
85 line = ''
93 line = ''
86 while True:
94 while True:
87 line = (yield line)
95 line = (yield line)
88
96
89 if line is None:
97 if line is None:
90 continue
98 continue
91
99
92 m = space_re.match(line)
100 m = space_re.match(line)
93 if m:
101 if m:
94 space = m.group(0)
102 space = m.group(0)
95 while line is not None:
103 while line is not None:
96 if line.startswith(space):
104 if line.startswith(space):
97 line = line[len(space):]
105 line = line[len(space):]
98 line = (yield line)
106 line = (yield line)
99 else:
107 else:
100 # No leading spaces - wait for reset
108 # No leading spaces - wait for reset
101 while line is not None:
109 while line is not None:
102 line = (yield line)
110 line = (yield line)
103
111
104 leading_indent.look_in_string = True
112 leading_indent.look_in_string = True
105
113
106 Token-based transformers
114 Token-based transformers
107 ------------------------
115 ------------------------
108
116
109 There is an experimental framework that takes care of tokenizing and
117 There is an experimental framework that takes care of tokenizing and
110 untokenizing lines of code. Define a function that accepts a list of tokens, and
118 untokenizing lines of code. Define a function that accepts a list of tokens, and
111 returns an iterable of output tokens, and decorate it with
119 returns an iterable of output tokens, and decorate it with
112 :meth:`TokenInputTransformer.wrap`. These should only be used in
120 :meth:`TokenInputTransformer.wrap`. These should only be used in
113 ``python_line_transforms``.
121 ``python_line_transforms``.
114
122
115 AST transformations
123 AST transformations
116 ===================
124 ===================
117
125
118 After the code has been parsed as Python syntax, you can use Python's powerful
126 After the code has been parsed as Python syntax, you can use Python's powerful
119 *Abstract Syntax Tree* tools to modify it. Subclass :class:`ast.NodeTransformer`,
127 *Abstract Syntax Tree* tools to modify it. Subclass :class:`ast.NodeTransformer`,
120 and add an instance to ``shell.ast_transformers``.
128 and add an instance to ``shell.ast_transformers``.
121
129
122 This example wraps integer literals in an ``Integer`` class, which is useful for
130 This example wraps integer literals in an ``Integer`` class, which is useful for
123 mathematical frameworks that want to handle e.g. ``1/3`` as a precise fraction::
131 mathematical frameworks that want to handle e.g. ``1/3`` as a precise fraction::
124
132
125
133
126 class IntegerWrapper(ast.NodeTransformer):
134 class IntegerWrapper(ast.NodeTransformer):
127 """Wraps all integers in a call to Integer()"""
135 """Wraps all integers in a call to Integer()"""
128 def visit_Num(self, node):
136 def visit_Num(self, node):
129 if isinstance(node.n, int):
137 if isinstance(node.n, int):
130 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
138 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
131 args=[node], keywords=[])
139 args=[node], keywords=[])
132 return node
140 return node
General Comments 0
You need to be logged in to leave comments. Login now