##// END OF EJS Templates
Merge pull request #10134 from srinivasreddy/rm_PY3...
Thomas Kluyver -
r23128:3a5799a9 merge
parent child Browse files
Show More
@@ -1,1229 +1,1227 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Word completion for IPython.
2 """Word completion for IPython.
3
3
4 This module started as fork of the rlcompleter module in the Python standard
4 This module started as fork of the rlcompleter module in the Python standard
5 library. The original enhancements made to rlcompleter have been sent
5 library. The original enhancements made to rlcompleter have been sent
6 upstream and were accepted as of Python 2.3,
6 upstream and were accepted as of Python 2.3,
7
7
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12 #
12 #
13 # Some of this code originated from rlcompleter in the Python standard library
13 # Some of this code originated from rlcompleter in the Python standard library
14 # Copyright (C) 2001 Python Software Foundation, www.python.org
14 # Copyright (C) 2001 Python Software Foundation, www.python.org
15
15
16
16
17 import __main__
17 import __main__
18 import glob
18 import glob
19 import inspect
19 import inspect
20 import itertools
20 import itertools
21 import keyword
21 import keyword
22 import os
22 import os
23 import re
23 import re
24 import sys
24 import sys
25 import unicodedata
25 import unicodedata
26 import string
26 import string
27 import warnings
27 import warnings
28 from importlib import import_module
28 from importlib import import_module
29
29
30 from traitlets.config.configurable import Configurable
30 from traitlets.config.configurable import Configurable
31 from IPython.core.error import TryNext
31 from IPython.core.error import TryNext
32 from IPython.core.inputsplitter import ESC_MAGIC
32 from IPython.core.inputsplitter import ESC_MAGIC
33 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
33 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
34 from IPython.utils import generics
34 from IPython.utils import generics
35 from IPython.utils.decorators import undoc
35 from IPython.utils.decorators import undoc
36 from IPython.utils.dir2 import dir2, get_real_method
36 from IPython.utils.dir2 import dir2, get_real_method
37 from IPython.utils.process import arg_split
37 from IPython.utils.process import arg_split
38 from IPython.utils.py3compat import builtin_mod, PY3, cast_unicode_py2
38 from IPython.utils.py3compat import builtin_mod, cast_unicode_py2
39 from traitlets import Bool, Enum, observe
39 from traitlets import Bool, Enum, observe
40
40
41 from functools import wraps
41 from functools import wraps
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Globals
44 # Globals
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 # Public API
47 # Public API
48 __all__ = ['Completer','IPCompleter']
48 __all__ = ['Completer','IPCompleter']
49
49
50 if sys.platform == 'win32':
50 if sys.platform == 'win32':
51 PROTECTABLES = ' '
51 PROTECTABLES = ' '
52 else:
52 else:
53 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
53 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
54
54
55
55
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57 # Work around BUG decorators.
57 # Work around BUG decorators.
58 #-----------------------------------------------------------------------------
58 #-----------------------------------------------------------------------------
59
59
60 def _strip_single_trailing_space(complete):
60 def _strip_single_trailing_space(complete):
61 """
61 """
62 This is a workaround for a weird IPython/Prompt_toolkit behavior,
62 This is a workaround for a weird IPython/Prompt_toolkit behavior,
63 that can be removed once we rely on a slightly more recent prompt_toolkit
63 that can be removed once we rely on a slightly more recent prompt_toolkit
64 version (likely > 1.0.3). So this can likely be removed in IPython 6.0
64 version (likely > 1.0.3). So this can likely be removed in IPython 6.0
65
65
66 cf https://github.com/ipython/ipython/issues/9658
66 cf https://github.com/ipython/ipython/issues/9658
67 and https://github.com/jonathanslenders/python-prompt-toolkit/pull/328
67 and https://github.com/jonathanslenders/python-prompt-toolkit/pull/328
68
68
69 The bug is due to the fact that in PTK the completer will reinvoke itself
69 The bug is due to the fact that in PTK the completer will reinvoke itself
70 after trying to completer to the longuest common prefix of all the
70 after trying to completer to the longuest common prefix of all the
71 completions, unless only one completion is available.
71 completions, unless only one completion is available.
72
72
73 This logic is faulty if the completion ends with space, which can happen in
73 This logic is faulty if the completion ends with space, which can happen in
74 case like::
74 case like::
75
75
76 from foo import im<ta>
76 from foo import im<ta>
77
77
78 which only matching completion is `import `. Note the leading space at the
78 which only matching completion is `import `. Note the leading space at the
79 end. So leaving a space at the end is a reasonable request, but for now
79 end. So leaving a space at the end is a reasonable request, but for now
80 we'll strip it.
80 we'll strip it.
81 """
81 """
82
82
83 @wraps(complete)
83 @wraps(complete)
84 def comp(*args, **kwargs):
84 def comp(*args, **kwargs):
85 text, matches = complete(*args, **kwargs)
85 text, matches = complete(*args, **kwargs)
86 if len(matches) == 1:
86 if len(matches) == 1:
87 return text, [matches[0].rstrip()]
87 return text, [matches[0].rstrip()]
88 return text, matches
88 return text, matches
89
89
90 return comp
90 return comp
91
91
92
92
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Main functions and classes
95 # Main functions and classes
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97
97
98 def has_open_quotes(s):
98 def has_open_quotes(s):
99 """Return whether a string has open quotes.
99 """Return whether a string has open quotes.
100
100
101 This simply counts whether the number of quote characters of either type in
101 This simply counts whether the number of quote characters of either type in
102 the string is odd.
102 the string is odd.
103
103
104 Returns
104 Returns
105 -------
105 -------
106 If there is an open quote, the quote character is returned. Else, return
106 If there is an open quote, the quote character is returned. Else, return
107 False.
107 False.
108 """
108 """
109 # We check " first, then ', so complex cases with nested quotes will get
109 # We check " first, then ', so complex cases with nested quotes will get
110 # the " to take precedence.
110 # the " to take precedence.
111 if s.count('"') % 2:
111 if s.count('"') % 2:
112 return '"'
112 return '"'
113 elif s.count("'") % 2:
113 elif s.count("'") % 2:
114 return "'"
114 return "'"
115 else:
115 else:
116 return False
116 return False
117
117
118
118
119 def protect_filename(s):
119 def protect_filename(s):
120 """Escape a string to protect certain characters."""
120 """Escape a string to protect certain characters."""
121 if set(s) & set(PROTECTABLES):
121 if set(s) & set(PROTECTABLES):
122 if sys.platform == "win32":
122 if sys.platform == "win32":
123 return '"' + s + '"'
123 return '"' + s + '"'
124 else:
124 else:
125 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
125 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
126 else:
126 else:
127 return s
127 return s
128
128
129
129
130 def expand_user(path):
130 def expand_user(path):
131 """Expand '~'-style usernames in strings.
131 """Expand '~'-style usernames in strings.
132
132
133 This is similar to :func:`os.path.expanduser`, but it computes and returns
133 This is similar to :func:`os.path.expanduser`, but it computes and returns
134 extra information that will be useful if the input was being used in
134 extra information that will be useful if the input was being used in
135 computing completions, and you wish to return the completions with the
135 computing completions, and you wish to return the completions with the
136 original '~' instead of its expanded value.
136 original '~' instead of its expanded value.
137
137
138 Parameters
138 Parameters
139 ----------
139 ----------
140 path : str
140 path : str
141 String to be expanded. If no ~ is present, the output is the same as the
141 String to be expanded. If no ~ is present, the output is the same as the
142 input.
142 input.
143
143
144 Returns
144 Returns
145 -------
145 -------
146 newpath : str
146 newpath : str
147 Result of ~ expansion in the input path.
147 Result of ~ expansion in the input path.
148 tilde_expand : bool
148 tilde_expand : bool
149 Whether any expansion was performed or not.
149 Whether any expansion was performed or not.
150 tilde_val : str
150 tilde_val : str
151 The value that ~ was replaced with.
151 The value that ~ was replaced with.
152 """
152 """
153 # Default values
153 # Default values
154 tilde_expand = False
154 tilde_expand = False
155 tilde_val = ''
155 tilde_val = ''
156 newpath = path
156 newpath = path
157
157
158 if path.startswith('~'):
158 if path.startswith('~'):
159 tilde_expand = True
159 tilde_expand = True
160 rest = len(path)-1
160 rest = len(path)-1
161 newpath = os.path.expanduser(path)
161 newpath = os.path.expanduser(path)
162 if rest:
162 if rest:
163 tilde_val = newpath[:-rest]
163 tilde_val = newpath[:-rest]
164 else:
164 else:
165 tilde_val = newpath
165 tilde_val = newpath
166
166
167 return newpath, tilde_expand, tilde_val
167 return newpath, tilde_expand, tilde_val
168
168
169
169
170 def compress_user(path, tilde_expand, tilde_val):
170 def compress_user(path, tilde_expand, tilde_val):
171 """Does the opposite of expand_user, with its outputs.
171 """Does the opposite of expand_user, with its outputs.
172 """
172 """
173 if tilde_expand:
173 if tilde_expand:
174 return path.replace(tilde_val, '~')
174 return path.replace(tilde_val, '~')
175 else:
175 else:
176 return path
176 return path
177
177
178
178
179 def completions_sorting_key(word):
179 def completions_sorting_key(word):
180 """key for sorting completions
180 """key for sorting completions
181
181
182 This does several things:
182 This does several things:
183
183
184 - Lowercase all completions, so they are sorted alphabetically with
184 - Lowercase all completions, so they are sorted alphabetically with
185 upper and lower case words mingled
185 upper and lower case words mingled
186 - Demote any completions starting with underscores to the end
186 - Demote any completions starting with underscores to the end
187 - Insert any %magic and %%cellmagic completions in the alphabetical order
187 - Insert any %magic and %%cellmagic completions in the alphabetical order
188 by their name
188 by their name
189 """
189 """
190 # Case insensitive sort
190 # Case insensitive sort
191 word = word.lower()
191 word = word.lower()
192
192
193 prio1, prio2 = 0, 0
193 prio1, prio2 = 0, 0
194
194
195 if word.startswith('__'):
195 if word.startswith('__'):
196 prio1 = 2
196 prio1 = 2
197 elif word.startswith('_'):
197 elif word.startswith('_'):
198 prio1 = 1
198 prio1 = 1
199
199
200 if word.endswith('='):
200 if word.endswith('='):
201 prio1 = -1
201 prio1 = -1
202
202
203 if word.startswith('%%'):
203 if word.startswith('%%'):
204 # If there's another % in there, this is something else, so leave it alone
204 # If there's another % in there, this is something else, so leave it alone
205 if not "%" in word[2:]:
205 if not "%" in word[2:]:
206 word = word[2:]
206 word = word[2:]
207 prio2 = 2
207 prio2 = 2
208 elif word.startswith('%'):
208 elif word.startswith('%'):
209 if not "%" in word[1:]:
209 if not "%" in word[1:]:
210 word = word[1:]
210 word = word[1:]
211 prio2 = 1
211 prio2 = 1
212
212
213 return prio1, word, prio2
213 return prio1, word, prio2
214
214
215
215
216 @undoc
216 @undoc
217 class Bunch(object): pass
217 class Bunch(object): pass
218
218
219
219
220 if sys.platform == 'win32':
220 if sys.platform == 'win32':
221 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
221 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
222 else:
222 else:
223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
224
224
225 GREEDY_DELIMS = ' =\r\n'
225 GREEDY_DELIMS = ' =\r\n'
226
226
227
227
228 class CompletionSplitter(object):
228 class CompletionSplitter(object):
229 """An object to split an input line in a manner similar to readline.
229 """An object to split an input line in a manner similar to readline.
230
230
231 By having our own implementation, we can expose readline-like completion in
231 By having our own implementation, we can expose readline-like completion in
232 a uniform manner to all frontends. This object only needs to be given the
232 a uniform manner to all frontends. This object only needs to be given the
233 line of text to be split and the cursor position on said line, and it
233 line of text to be split and the cursor position on said line, and it
234 returns the 'word' to be completed on at the cursor after splitting the
234 returns the 'word' to be completed on at the cursor after splitting the
235 entire line.
235 entire line.
236
236
237 What characters are used as splitting delimiters can be controlled by
237 What characters are used as splitting delimiters can be controlled by
238 setting the `delims` attribute (this is a property that internally
238 setting the `delims` attribute (this is a property that internally
239 automatically builds the necessary regular expression)"""
239 automatically builds the necessary regular expression)"""
240
240
241 # Private interface
241 # Private interface
242
242
243 # A string of delimiter characters. The default value makes sense for
243 # A string of delimiter characters. The default value makes sense for
244 # IPython's most typical usage patterns.
244 # IPython's most typical usage patterns.
245 _delims = DELIMS
245 _delims = DELIMS
246
246
247 # The expression (a normal string) to be compiled into a regular expression
247 # The expression (a normal string) to be compiled into a regular expression
248 # for actual splitting. We store it as an attribute mostly for ease of
248 # for actual splitting. We store it as an attribute mostly for ease of
249 # debugging, since this type of code can be so tricky to debug.
249 # debugging, since this type of code can be so tricky to debug.
250 _delim_expr = None
250 _delim_expr = None
251
251
252 # The regular expression that does the actual splitting
252 # The regular expression that does the actual splitting
253 _delim_re = None
253 _delim_re = None
254
254
255 def __init__(self, delims=None):
255 def __init__(self, delims=None):
256 delims = CompletionSplitter._delims if delims is None else delims
256 delims = CompletionSplitter._delims if delims is None else delims
257 self.delims = delims
257 self.delims = delims
258
258
259 @property
259 @property
260 def delims(self):
260 def delims(self):
261 """Return the string of delimiter characters."""
261 """Return the string of delimiter characters."""
262 return self._delims
262 return self._delims
263
263
264 @delims.setter
264 @delims.setter
265 def delims(self, delims):
265 def delims(self, delims):
266 """Set the delimiters for line splitting."""
266 """Set the delimiters for line splitting."""
267 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
267 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
268 self._delim_re = re.compile(expr)
268 self._delim_re = re.compile(expr)
269 self._delims = delims
269 self._delims = delims
270 self._delim_expr = expr
270 self._delim_expr = expr
271
271
272 def split_line(self, line, cursor_pos=None):
272 def split_line(self, line, cursor_pos=None):
273 """Split a line of text with a cursor at the given position.
273 """Split a line of text with a cursor at the given position.
274 """
274 """
275 l = line if cursor_pos is None else line[:cursor_pos]
275 l = line if cursor_pos is None else line[:cursor_pos]
276 return self._delim_re.split(l)[-1]
276 return self._delim_re.split(l)[-1]
277
277
278
278
279 class Completer(Configurable):
279 class Completer(Configurable):
280
280
281 greedy = Bool(False,
281 greedy = Bool(False,
282 help="""Activate greedy completion
282 help="""Activate greedy completion
283 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
283 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
284
284
285 This will enable completion on elements of lists, results of function calls, etc.,
285 This will enable completion on elements of lists, results of function calls, etc.,
286 but can be unsafe because the code is actually evaluated on TAB.
286 but can be unsafe because the code is actually evaluated on TAB.
287 """
287 """
288 ).tag(config=True)
288 ).tag(config=True)
289
289
290
290
291 def __init__(self, namespace=None, global_namespace=None, **kwargs):
291 def __init__(self, namespace=None, global_namespace=None, **kwargs):
292 """Create a new completer for the command line.
292 """Create a new completer for the command line.
293
293
294 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
294 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
295
295
296 If unspecified, the default namespace where completions are performed
296 If unspecified, the default namespace where completions are performed
297 is __main__ (technically, __main__.__dict__). Namespaces should be
297 is __main__ (technically, __main__.__dict__). Namespaces should be
298 given as dictionaries.
298 given as dictionaries.
299
299
300 An optional second namespace can be given. This allows the completer
300 An optional second namespace can be given. This allows the completer
301 to handle cases where both the local and global scopes need to be
301 to handle cases where both the local and global scopes need to be
302 distinguished.
302 distinguished.
303
303
304 Completer instances should be used as the completion mechanism of
304 Completer instances should be used as the completion mechanism of
305 readline via the set_completer() call:
305 readline via the set_completer() call:
306
306
307 readline.set_completer(Completer(my_namespace).complete)
307 readline.set_completer(Completer(my_namespace).complete)
308 """
308 """
309
309
310 # Don't bind to namespace quite yet, but flag whether the user wants a
310 # Don't bind to namespace quite yet, but flag whether the user wants a
311 # specific namespace or to use __main__.__dict__. This will allow us
311 # specific namespace or to use __main__.__dict__. This will allow us
312 # to bind to __main__.__dict__ at completion time, not now.
312 # to bind to __main__.__dict__ at completion time, not now.
313 if namespace is None:
313 if namespace is None:
314 self.use_main_ns = 1
314 self.use_main_ns = 1
315 else:
315 else:
316 self.use_main_ns = 0
316 self.use_main_ns = 0
317 self.namespace = namespace
317 self.namespace = namespace
318
318
319 # The global namespace, if given, can be bound directly
319 # The global namespace, if given, can be bound directly
320 if global_namespace is None:
320 if global_namespace is None:
321 self.global_namespace = {}
321 self.global_namespace = {}
322 else:
322 else:
323 self.global_namespace = global_namespace
323 self.global_namespace = global_namespace
324
324
325 super(Completer, self).__init__(**kwargs)
325 super(Completer, self).__init__(**kwargs)
326
326
327 def complete(self, text, state):
327 def complete(self, text, state):
328 """Return the next possible completion for 'text'.
328 """Return the next possible completion for 'text'.
329
329
330 This is called successively with state == 0, 1, 2, ... until it
330 This is called successively with state == 0, 1, 2, ... until it
331 returns None. The completion should begin with 'text'.
331 returns None. The completion should begin with 'text'.
332
332
333 """
333 """
334 if self.use_main_ns:
334 if self.use_main_ns:
335 self.namespace = __main__.__dict__
335 self.namespace = __main__.__dict__
336
336
337 if state == 0:
337 if state == 0:
338 if "." in text:
338 if "." in text:
339 self.matches = self.attr_matches(text)
339 self.matches = self.attr_matches(text)
340 else:
340 else:
341 self.matches = self.global_matches(text)
341 self.matches = self.global_matches(text)
342 try:
342 try:
343 return self.matches[state]
343 return self.matches[state]
344 except IndexError:
344 except IndexError:
345 return None
345 return None
346
346
347 def global_matches(self, text):
347 def global_matches(self, text):
348 """Compute matches when text is a simple name.
348 """Compute matches when text is a simple name.
349
349
350 Return a list of all keywords, built-in functions and names currently
350 Return a list of all keywords, built-in functions and names currently
351 defined in self.namespace or self.global_namespace that match.
351 defined in self.namespace or self.global_namespace that match.
352
352
353 """
353 """
354 matches = []
354 matches = []
355 match_append = matches.append
355 match_append = matches.append
356 n = len(text)
356 n = len(text)
357 for lst in [keyword.kwlist,
357 for lst in [keyword.kwlist,
358 builtin_mod.__dict__.keys(),
358 builtin_mod.__dict__.keys(),
359 self.namespace.keys(),
359 self.namespace.keys(),
360 self.global_namespace.keys()]:
360 self.global_namespace.keys()]:
361 for word in lst:
361 for word in lst:
362 if word[:n] == text and word != "__builtins__":
362 if word[:n] == text and word != "__builtins__":
363 match_append(word)
363 match_append(word)
364 return [cast_unicode_py2(m) for m in matches]
364 return [cast_unicode_py2(m) for m in matches]
365
365
366 def attr_matches(self, text):
366 def attr_matches(self, text):
367 """Compute matches when text contains a dot.
367 """Compute matches when text contains a dot.
368
368
369 Assuming the text is of the form NAME.NAME....[NAME], and is
369 Assuming the text is of the form NAME.NAME....[NAME], and is
370 evaluatable in self.namespace or self.global_namespace, it will be
370 evaluatable in self.namespace or self.global_namespace, it will be
371 evaluated and its attributes (as revealed by dir()) are used as
371 evaluated and its attributes (as revealed by dir()) are used as
372 possible completions. (For class instances, class members are are
372 possible completions. (For class instances, class members are are
373 also considered.)
373 also considered.)
374
374
375 WARNING: this can still invoke arbitrary C code, if an object
375 WARNING: this can still invoke arbitrary C code, if an object
376 with a __getattr__ hook is evaluated.
376 with a __getattr__ hook is evaluated.
377
377
378 """
378 """
379
379
380 # Another option, seems to work great. Catches things like ''.<tab>
380 # Another option, seems to work great. Catches things like ''.<tab>
381 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
381 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
382
382
383 if m:
383 if m:
384 expr, attr = m.group(1, 3)
384 expr, attr = m.group(1, 3)
385 elif self.greedy:
385 elif self.greedy:
386 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
386 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
387 if not m2:
387 if not m2:
388 return []
388 return []
389 expr, attr = m2.group(1,2)
389 expr, attr = m2.group(1,2)
390 else:
390 else:
391 return []
391 return []
392
392
393 try:
393 try:
394 obj = eval(expr, self.namespace)
394 obj = eval(expr, self.namespace)
395 except:
395 except:
396 try:
396 try:
397 obj = eval(expr, self.global_namespace)
397 obj = eval(expr, self.global_namespace)
398 except:
398 except:
399 return []
399 return []
400
400
401 if self.limit_to__all__ and hasattr(obj, '__all__'):
401 if self.limit_to__all__ and hasattr(obj, '__all__'):
402 words = get__all__entries(obj)
402 words = get__all__entries(obj)
403 else:
403 else:
404 words = dir2(obj)
404 words = dir2(obj)
405
405
406 try:
406 try:
407 words = generics.complete_object(obj, words)
407 words = generics.complete_object(obj, words)
408 except TryNext:
408 except TryNext:
409 pass
409 pass
410 except Exception:
410 except Exception:
411 # Silence errors from completion function
411 # Silence errors from completion function
412 #raise # dbg
412 #raise # dbg
413 pass
413 pass
414 # Build match list to return
414 # Build match list to return
415 n = len(attr)
415 n = len(attr)
416 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
416 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
417
417
418
418
419 def get__all__entries(obj):
419 def get__all__entries(obj):
420 """returns the strings in the __all__ attribute"""
420 """returns the strings in the __all__ attribute"""
421 try:
421 try:
422 words = getattr(obj, '__all__')
422 words = getattr(obj, '__all__')
423 except:
423 except:
424 return []
424 return []
425
425
426 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
426 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
427
427
428
428
429 def match_dict_keys(keys, prefix, delims):
429 def match_dict_keys(keys, prefix, delims):
430 """Used by dict_key_matches, matching the prefix to a list of keys"""
430 """Used by dict_key_matches, matching the prefix to a list of keys"""
431 if not prefix:
431 if not prefix:
432 return None, 0, [repr(k) for k in keys
432 return None, 0, [repr(k) for k in keys
433 if isinstance(k, (str, bytes))]
433 if isinstance(k, (str, bytes))]
434 quote_match = re.search('["\']', prefix)
434 quote_match = re.search('["\']', prefix)
435 quote = quote_match.group()
435 quote = quote_match.group()
436 try:
436 try:
437 prefix_str = eval(prefix + quote, {})
437 prefix_str = eval(prefix + quote, {})
438 except Exception:
438 except Exception:
439 return None, 0, []
439 return None, 0, []
440
440
441 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
441 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
442 token_match = re.search(pattern, prefix, re.UNICODE)
442 token_match = re.search(pattern, prefix, re.UNICODE)
443 token_start = token_match.start()
443 token_start = token_match.start()
444 token_prefix = token_match.group()
444 token_prefix = token_match.group()
445
445
446 # TODO: support bytes in Py3k
446 # TODO: support bytes in Py3k
447 matched = []
447 matched = []
448 for key in keys:
448 for key in keys:
449 try:
449 try:
450 if not key.startswith(prefix_str):
450 if not key.startswith(prefix_str):
451 continue
451 continue
452 except (AttributeError, TypeError, UnicodeError):
452 except (AttributeError, TypeError, UnicodeError):
453 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
453 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
454 continue
454 continue
455
455
456 # reformat remainder of key to begin with prefix
456 # reformat remainder of key to begin with prefix
457 rem = key[len(prefix_str):]
457 rem = key[len(prefix_str):]
458 # force repr wrapped in '
458 # force repr wrapped in '
459 rem_repr = repr(rem + '"')
459 rem_repr = repr(rem + '"')
460 if rem_repr.startswith('u') and prefix[0] not in 'uU':
460 if rem_repr.startswith('u') and prefix[0] not in 'uU':
461 # Found key is unicode, but prefix is Py2 string.
461 # Found key is unicode, but prefix is Py2 string.
462 # Therefore attempt to interpret key as string.
462 # Therefore attempt to interpret key as string.
463 try:
463 try:
464 rem_repr = repr(rem.encode('ascii') + '"')
464 rem_repr = repr(rem.encode('ascii') + '"')
465 except UnicodeEncodeError:
465 except UnicodeEncodeError:
466 continue
466 continue
467
467
468 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
468 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
469 if quote == '"':
469 if quote == '"':
470 # The entered prefix is quoted with ",
470 # The entered prefix is quoted with ",
471 # but the match is quoted with '.
471 # but the match is quoted with '.
472 # A contained " hence needs escaping for comparison:
472 # A contained " hence needs escaping for comparison:
473 rem_repr = rem_repr.replace('"', '\\"')
473 rem_repr = rem_repr.replace('"', '\\"')
474
474
475 # then reinsert prefix from start of token
475 # then reinsert prefix from start of token
476 matched.append('%s%s' % (token_prefix, rem_repr))
476 matched.append('%s%s' % (token_prefix, rem_repr))
477 return quote, token_start, matched
477 return quote, token_start, matched
478
478
479
479
480 def _safe_isinstance(obj, module, class_name):
480 def _safe_isinstance(obj, module, class_name):
481 """Checks if obj is an instance of module.class_name if loaded
481 """Checks if obj is an instance of module.class_name if loaded
482 """
482 """
483 return (module in sys.modules and
483 return (module in sys.modules and
484 isinstance(obj, getattr(import_module(module), class_name)))
484 isinstance(obj, getattr(import_module(module), class_name)))
485
485
486
486
487 def back_unicode_name_matches(text):
487 def back_unicode_name_matches(text):
488 u"""Match unicode characters back to unicode name
488 u"""Match unicode characters back to unicode name
489
489
490 This does β˜ƒ -> \\snowman
490 This does β˜ƒ -> \\snowman
491
491
492 Note that snowman is not a valid python3 combining character but will be expanded.
492 Note that snowman is not a valid python3 combining character but will be expanded.
493 Though it will not recombine back to the snowman character by the completion machinery.
493 Though it will not recombine back to the snowman character by the completion machinery.
494
494
495 This will not either back-complete standard sequences like \\n, \\b ...
495 This will not either back-complete standard sequences like \\n, \\b ...
496
496
497 Used on Python 3 only.
497 Used on Python 3 only.
498 """
498 """
499 if len(text)<2:
499 if len(text)<2:
500 return u'', ()
500 return u'', ()
501 maybe_slash = text[-2]
501 maybe_slash = text[-2]
502 if maybe_slash != '\\':
502 if maybe_slash != '\\':
503 return u'', ()
503 return u'', ()
504
504
505 char = text[-1]
505 char = text[-1]
506 # no expand on quote for completion in strings.
506 # no expand on quote for completion in strings.
507 # nor backcomplete standard ascii keys
507 # nor backcomplete standard ascii keys
508 if char in string.ascii_letters or char in ['"',"'"]:
508 if char in string.ascii_letters or char in ['"',"'"]:
509 return u'', ()
509 return u'', ()
510 try :
510 try :
511 unic = unicodedata.name(char)
511 unic = unicodedata.name(char)
512 return '\\'+char,['\\'+unic]
512 return '\\'+char,['\\'+unic]
513 except KeyError:
513 except KeyError:
514 pass
514 pass
515 return u'', ()
515 return u'', ()
516
516
517 def back_latex_name_matches(text):
517 def back_latex_name_matches(text):
518 u"""Match latex characters back to unicode name
518 u"""Match latex characters back to unicode name
519
519
520 This does ->\\sqrt
520 This does ->\\sqrt
521
521
522 Used on Python 3 only.
522 Used on Python 3 only.
523 """
523 """
524 if len(text)<2:
524 if len(text)<2:
525 return u'', ()
525 return u'', ()
526 maybe_slash = text[-2]
526 maybe_slash = text[-2]
527 if maybe_slash != '\\':
527 if maybe_slash != '\\':
528 return u'', ()
528 return u'', ()
529
529
530
530
531 char = text[-1]
531 char = text[-1]
532 # no expand on quote for completion in strings.
532 # no expand on quote for completion in strings.
533 # nor backcomplete standard ascii keys
533 # nor backcomplete standard ascii keys
534 if char in string.ascii_letters or char in ['"',"'"]:
534 if char in string.ascii_letters or char in ['"',"'"]:
535 return u'', ()
535 return u'', ()
536 try :
536 try :
537 latex = reverse_latex_symbol[char]
537 latex = reverse_latex_symbol[char]
538 # '\\' replace the \ as well
538 # '\\' replace the \ as well
539 return '\\'+char,[latex]
539 return '\\'+char,[latex]
540 except KeyError:
540 except KeyError:
541 pass
541 pass
542 return u'', ()
542 return u'', ()
543
543
544
544
545 class IPCompleter(Completer):
545 class IPCompleter(Completer):
546 """Extension of the completer class with IPython-specific features"""
546 """Extension of the completer class with IPython-specific features"""
547
547
548 @observe('greedy')
548 @observe('greedy')
549 def _greedy_changed(self, change):
549 def _greedy_changed(self, change):
550 """update the splitter and readline delims when greedy is changed"""
550 """update the splitter and readline delims when greedy is changed"""
551 if change['new']:
551 if change['new']:
552 self.splitter.delims = GREEDY_DELIMS
552 self.splitter.delims = GREEDY_DELIMS
553 else:
553 else:
554 self.splitter.delims = DELIMS
554 self.splitter.delims = DELIMS
555
555
556 merge_completions = Bool(True,
556 merge_completions = Bool(True,
557 help="""Whether to merge completion results into a single list
557 help="""Whether to merge completion results into a single list
558
558
559 If False, only the completion results from the first non-empty
559 If False, only the completion results from the first non-empty
560 completer will be returned.
560 completer will be returned.
561 """
561 """
562 ).tag(config=True)
562 ).tag(config=True)
563 omit__names = Enum((0,1,2), default_value=2,
563 omit__names = Enum((0,1,2), default_value=2,
564 help="""Instruct the completer to omit private method names
564 help="""Instruct the completer to omit private method names
565
565
566 Specifically, when completing on ``object.<tab>``.
566 Specifically, when completing on ``object.<tab>``.
567
567
568 When 2 [default]: all names that start with '_' will be excluded.
568 When 2 [default]: all names that start with '_' will be excluded.
569
569
570 When 1: all 'magic' names (``__foo__``) will be excluded.
570 When 1: all 'magic' names (``__foo__``) will be excluded.
571
571
572 When 0: nothing will be excluded.
572 When 0: nothing will be excluded.
573 """
573 """
574 ).tag(config=True)
574 ).tag(config=True)
575 limit_to__all__ = Bool(False,
575 limit_to__all__ = Bool(False,
576 help="""
576 help="""
577 DEPRECATED as of version 5.0.
577 DEPRECATED as of version 5.0.
578
578
579 Instruct the completer to use __all__ for the completion
579 Instruct the completer to use __all__ for the completion
580
580
581 Specifically, when completing on ``object.<tab>``.
581 Specifically, when completing on ``object.<tab>``.
582
582
583 When True: only those names in obj.__all__ will be included.
583 When True: only those names in obj.__all__ will be included.
584
584
585 When False [default]: the __all__ attribute is ignored
585 When False [default]: the __all__ attribute is ignored
586 """,
586 """,
587 ).tag(config=True)
587 ).tag(config=True)
588
588
589 def __init__(self, shell=None, namespace=None, global_namespace=None,
589 def __init__(self, shell=None, namespace=None, global_namespace=None,
590 use_readline=False, config=None, **kwargs):
590 use_readline=False, config=None, **kwargs):
591 """IPCompleter() -> completer
591 """IPCompleter() -> completer
592
592
593 Return a completer object suitable for use by the readline library
593 Return a completer object suitable for use by the readline library
594 via readline.set_completer().
594 via readline.set_completer().
595
595
596 Inputs:
596 Inputs:
597
597
598 - shell: a pointer to the ipython shell itself. This is needed
598 - shell: a pointer to the ipython shell itself. This is needed
599 because this completer knows about magic functions, and those can
599 because this completer knows about magic functions, and those can
600 only be accessed via the ipython instance.
600 only be accessed via the ipython instance.
601
601
602 - namespace: an optional dict where completions are performed.
602 - namespace: an optional dict where completions are performed.
603
603
604 - global_namespace: secondary optional dict for completions, to
604 - global_namespace: secondary optional dict for completions, to
605 handle cases (such as IPython embedded inside functions) where
605 handle cases (such as IPython embedded inside functions) where
606 both Python scopes are visible.
606 both Python scopes are visible.
607
607
608 use_readline : bool, optional
608 use_readline : bool, optional
609 DEPRECATED, ignored.
609 DEPRECATED, ignored.
610 """
610 """
611
611
612 self.magic_escape = ESC_MAGIC
612 self.magic_escape = ESC_MAGIC
613 self.splitter = CompletionSplitter()
613 self.splitter = CompletionSplitter()
614
614
615 if use_readline:
615 if use_readline:
616 warnings.warn('The use_readline parameter is deprecated and ignored since IPython 6.0.',
616 warnings.warn('The use_readline parameter is deprecated and ignored since IPython 6.0.',
617 DeprecationWarning, stacklevel=2)
617 DeprecationWarning, stacklevel=2)
618
618
619 # _greedy_changed() depends on splitter and readline being defined:
619 # _greedy_changed() depends on splitter and readline being defined:
620 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
620 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
621 config=config, **kwargs)
621 config=config, **kwargs)
622
622
623 # List where completion matches will be stored
623 # List where completion matches will be stored
624 self.matches = []
624 self.matches = []
625 self.shell = shell
625 self.shell = shell
626 # Regexp to split filenames with spaces in them
626 # Regexp to split filenames with spaces in them
627 self.space_name_re = re.compile(r'([^\\] )')
627 self.space_name_re = re.compile(r'([^\\] )')
628 # Hold a local ref. to glob.glob for speed
628 # Hold a local ref. to glob.glob for speed
629 self.glob = glob.glob
629 self.glob = glob.glob
630
630
631 # Determine if we are running on 'dumb' terminals, like (X)Emacs
631 # Determine if we are running on 'dumb' terminals, like (X)Emacs
632 # buffers, to avoid completion problems.
632 # buffers, to avoid completion problems.
633 term = os.environ.get('TERM','xterm')
633 term = os.environ.get('TERM','xterm')
634 self.dumb_terminal = term in ['dumb','emacs']
634 self.dumb_terminal = term in ['dumb','emacs']
635
635
636 # Special handling of backslashes needed in win32 platforms
636 # Special handling of backslashes needed in win32 platforms
637 if sys.platform == "win32":
637 if sys.platform == "win32":
638 self.clean_glob = self._clean_glob_win32
638 self.clean_glob = self._clean_glob_win32
639 else:
639 else:
640 self.clean_glob = self._clean_glob
640 self.clean_glob = self._clean_glob
641
641
642 #regexp to parse docstring for function signature
642 #regexp to parse docstring for function signature
643 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
643 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
644 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
644 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
645 #use this if positional argument name is also needed
645 #use this if positional argument name is also needed
646 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
646 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
647
647
648 # All active matcher routines for completion
648 # All active matcher routines for completion
649 self.matchers = [
649 self.matchers = [
650 self.python_matches,
650 self.python_matches,
651 self.file_matches,
651 self.file_matches,
652 self.magic_matches,
652 self.magic_matches,
653 self.python_func_kw_matches,
653 self.python_func_kw_matches,
654 self.dict_key_matches,
654 self.dict_key_matches,
655 ]
655 ]
656
656
657 # This is set externally by InteractiveShell
657 # This is set externally by InteractiveShell
658 self.custom_completers = None
658 self.custom_completers = None
659
659
660 def all_completions(self, text):
660 def all_completions(self, text):
661 """
661 """
662 Wrapper around the complete method for the benefit of emacs.
662 Wrapper around the complete method for the benefit of emacs.
663 """
663 """
664 return self.complete(text)[1]
664 return self.complete(text)[1]
665
665
666 def _clean_glob(self, text):
666 def _clean_glob(self, text):
667 return self.glob("%s*" % text)
667 return self.glob("%s*" % text)
668
668
669 def _clean_glob_win32(self,text):
669 def _clean_glob_win32(self,text):
670 return [f.replace("\\","/")
670 return [f.replace("\\","/")
671 for f in self.glob("%s*" % text)]
671 for f in self.glob("%s*" % text)]
672
672
673 def file_matches(self, text):
673 def file_matches(self, text):
674 """Match filenames, expanding ~USER type strings.
674 """Match filenames, expanding ~USER type strings.
675
675
676 Most of the seemingly convoluted logic in this completer is an
676 Most of the seemingly convoluted logic in this completer is an
677 attempt to handle filenames with spaces in them. And yet it's not
677 attempt to handle filenames with spaces in them. And yet it's not
678 quite perfect, because Python's readline doesn't expose all of the
678 quite perfect, because Python's readline doesn't expose all of the
679 GNU readline details needed for this to be done correctly.
679 GNU readline details needed for this to be done correctly.
680
680
681 For a filename with a space in it, the printed completions will be
681 For a filename with a space in it, the printed completions will be
682 only the parts after what's already been typed (instead of the
682 only the parts after what's already been typed (instead of the
683 full completions, as is normally done). I don't think with the
683 full completions, as is normally done). I don't think with the
684 current (as of Python 2.3) Python readline it's possible to do
684 current (as of Python 2.3) Python readline it's possible to do
685 better."""
685 better."""
686
686
687 # chars that require escaping with backslash - i.e. chars
687 # chars that require escaping with backslash - i.e. chars
688 # that readline treats incorrectly as delimiters, but we
688 # that readline treats incorrectly as delimiters, but we
689 # don't want to treat as delimiters in filename matching
689 # don't want to treat as delimiters in filename matching
690 # when escaped with backslash
690 # when escaped with backslash
691 if text.startswith('!'):
691 if text.startswith('!'):
692 text = text[1:]
692 text = text[1:]
693 text_prefix = u'!'
693 text_prefix = u'!'
694 else:
694 else:
695 text_prefix = u''
695 text_prefix = u''
696
696
697 text_until_cursor = self.text_until_cursor
697 text_until_cursor = self.text_until_cursor
698 # track strings with open quotes
698 # track strings with open quotes
699 open_quotes = has_open_quotes(text_until_cursor)
699 open_quotes = has_open_quotes(text_until_cursor)
700
700
701 if '(' in text_until_cursor or '[' in text_until_cursor:
701 if '(' in text_until_cursor or '[' in text_until_cursor:
702 lsplit = text
702 lsplit = text
703 else:
703 else:
704 try:
704 try:
705 # arg_split ~ shlex.split, but with unicode bugs fixed by us
705 # arg_split ~ shlex.split, but with unicode bugs fixed by us
706 lsplit = arg_split(text_until_cursor)[-1]
706 lsplit = arg_split(text_until_cursor)[-1]
707 except ValueError:
707 except ValueError:
708 # typically an unmatched ", or backslash without escaped char.
708 # typically an unmatched ", or backslash without escaped char.
709 if open_quotes:
709 if open_quotes:
710 lsplit = text_until_cursor.split(open_quotes)[-1]
710 lsplit = text_until_cursor.split(open_quotes)[-1]
711 else:
711 else:
712 return []
712 return []
713 except IndexError:
713 except IndexError:
714 # tab pressed on empty line
714 # tab pressed on empty line
715 lsplit = ""
715 lsplit = ""
716
716
717 if not open_quotes and lsplit != protect_filename(lsplit):
717 if not open_quotes and lsplit != protect_filename(lsplit):
718 # if protectables are found, do matching on the whole escaped name
718 # if protectables are found, do matching on the whole escaped name
719 has_protectables = True
719 has_protectables = True
720 text0,text = text,lsplit
720 text0,text = text,lsplit
721 else:
721 else:
722 has_protectables = False
722 has_protectables = False
723 text = os.path.expanduser(text)
723 text = os.path.expanduser(text)
724
724
725 if text == "":
725 if text == "":
726 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
726 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
727
727
728 # Compute the matches from the filesystem
728 # Compute the matches from the filesystem
729 if sys.platform == 'win32':
729 if sys.platform == 'win32':
730 m0 = self.clean_glob(text)
730 m0 = self.clean_glob(text)
731 else:
731 else:
732 m0 = self.clean_glob(text.replace('\\', ''))
732 m0 = self.clean_glob(text.replace('\\', ''))
733
733
734 if has_protectables:
734 if has_protectables:
735 # If we had protectables, we need to revert our changes to the
735 # If we had protectables, we need to revert our changes to the
736 # beginning of filename so that we don't double-write the part
736 # beginning of filename so that we don't double-write the part
737 # of the filename we have so far
737 # of the filename we have so far
738 len_lsplit = len(lsplit)
738 len_lsplit = len(lsplit)
739 matches = [text_prefix + text0 +
739 matches = [text_prefix + text0 +
740 protect_filename(f[len_lsplit:]) for f in m0]
740 protect_filename(f[len_lsplit:]) for f in m0]
741 else:
741 else:
742 if open_quotes:
742 if open_quotes:
743 # if we have a string with an open quote, we don't need to
743 # if we have a string with an open quote, we don't need to
744 # protect the names at all (and we _shouldn't_, as it
744 # protect the names at all (and we _shouldn't_, as it
745 # would cause bugs when the filesystem call is made).
745 # would cause bugs when the filesystem call is made).
746 matches = m0
746 matches = m0
747 else:
747 else:
748 matches = [text_prefix +
748 matches = [text_prefix +
749 protect_filename(f) for f in m0]
749 protect_filename(f) for f in m0]
750
750
751 # Mark directories in input list by appending '/' to their names.
751 # Mark directories in input list by appending '/' to their names.
752 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
752 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
753
753
754 def magic_matches(self, text):
754 def magic_matches(self, text):
755 """Match magics"""
755 """Match magics"""
756 # Get all shell magics now rather than statically, so magics loaded at
756 # Get all shell magics now rather than statically, so magics loaded at
757 # runtime show up too.
757 # runtime show up too.
758 lsm = self.shell.magics_manager.lsmagic()
758 lsm = self.shell.magics_manager.lsmagic()
759 line_magics = lsm['line']
759 line_magics = lsm['line']
760 cell_magics = lsm['cell']
760 cell_magics = lsm['cell']
761 pre = self.magic_escape
761 pre = self.magic_escape
762 pre2 = pre+pre
762 pre2 = pre+pre
763
763
764 # Completion logic:
764 # Completion logic:
765 # - user gives %%: only do cell magics
765 # - user gives %%: only do cell magics
766 # - user gives %: do both line and cell magics
766 # - user gives %: do both line and cell magics
767 # - no prefix: do both
767 # - no prefix: do both
768 # In other words, line magics are skipped if the user gives %% explicitly
768 # In other words, line magics are skipped if the user gives %% explicitly
769 bare_text = text.lstrip(pre)
769 bare_text = text.lstrip(pre)
770 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
770 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
771 if not text.startswith(pre2):
771 if not text.startswith(pre2):
772 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
772 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
773 return [cast_unicode_py2(c) for c in comp]
773 return [cast_unicode_py2(c) for c in comp]
774
774
775
775
776 def python_matches(self, text):
776 def python_matches(self, text):
777 """Match attributes or global python names"""
777 """Match attributes or global python names"""
778 if "." in text:
778 if "." in text:
779 try:
779 try:
780 matches = self.attr_matches(text)
780 matches = self.attr_matches(text)
781 if text.endswith('.') and self.omit__names:
781 if text.endswith('.') and self.omit__names:
782 if self.omit__names == 1:
782 if self.omit__names == 1:
783 # true if txt is _not_ a __ name, false otherwise:
783 # true if txt is _not_ a __ name, false otherwise:
784 no__name = (lambda txt:
784 no__name = (lambda txt:
785 re.match(r'.*\.__.*?__',txt) is None)
785 re.match(r'.*\.__.*?__',txt) is None)
786 else:
786 else:
787 # true if txt is _not_ a _ name, false otherwise:
787 # true if txt is _not_ a _ name, false otherwise:
788 no__name = (lambda txt:
788 no__name = (lambda txt:
789 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
789 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
790 matches = filter(no__name, matches)
790 matches = filter(no__name, matches)
791 except NameError:
791 except NameError:
792 # catches <undefined attributes>.<tab>
792 # catches <undefined attributes>.<tab>
793 matches = []
793 matches = []
794 else:
794 else:
795 matches = self.global_matches(text)
795 matches = self.global_matches(text)
796 return matches
796 return matches
797
797
798 def _default_arguments_from_docstring(self, doc):
798 def _default_arguments_from_docstring(self, doc):
799 """Parse the first line of docstring for call signature.
799 """Parse the first line of docstring for call signature.
800
800
801 Docstring should be of the form 'min(iterable[, key=func])\n'.
801 Docstring should be of the form 'min(iterable[, key=func])\n'.
802 It can also parse cython docstring of the form
802 It can also parse cython docstring of the form
803 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
803 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
804 """
804 """
805 if doc is None:
805 if doc is None:
806 return []
806 return []
807
807
808 #care only the firstline
808 #care only the firstline
809 line = doc.lstrip().splitlines()[0]
809 line = doc.lstrip().splitlines()[0]
810
810
811 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
811 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
812 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
812 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
813 sig = self.docstring_sig_re.search(line)
813 sig = self.docstring_sig_re.search(line)
814 if sig is None:
814 if sig is None:
815 return []
815 return []
816 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
816 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
817 sig = sig.groups()[0].split(',')
817 sig = sig.groups()[0].split(',')
818 ret = []
818 ret = []
819 for s in sig:
819 for s in sig:
820 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
820 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
821 ret += self.docstring_kwd_re.findall(s)
821 ret += self.docstring_kwd_re.findall(s)
822 return ret
822 return ret
823
823
824 def _default_arguments(self, obj):
824 def _default_arguments(self, obj):
825 """Return the list of default arguments of obj if it is callable,
825 """Return the list of default arguments of obj if it is callable,
826 or empty list otherwise."""
826 or empty list otherwise."""
827 call_obj = obj
827 call_obj = obj
828 ret = []
828 ret = []
829 if inspect.isbuiltin(obj):
829 if inspect.isbuiltin(obj):
830 pass
830 pass
831 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
831 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
832 if inspect.isclass(obj):
832 if inspect.isclass(obj):
833 #for cython embededsignature=True the constructor docstring
833 #for cython embededsignature=True the constructor docstring
834 #belongs to the object itself not __init__
834 #belongs to the object itself not __init__
835 ret += self._default_arguments_from_docstring(
835 ret += self._default_arguments_from_docstring(
836 getattr(obj, '__doc__', ''))
836 getattr(obj, '__doc__', ''))
837 # for classes, check for __init__,__new__
837 # for classes, check for __init__,__new__
838 call_obj = (getattr(obj, '__init__', None) or
838 call_obj = (getattr(obj, '__init__', None) or
839 getattr(obj, '__new__', None))
839 getattr(obj, '__new__', None))
840 # for all others, check if they are __call__able
840 # for all others, check if they are __call__able
841 elif hasattr(obj, '__call__'):
841 elif hasattr(obj, '__call__'):
842 call_obj = obj.__call__
842 call_obj = obj.__call__
843 ret += self._default_arguments_from_docstring(
843 ret += self._default_arguments_from_docstring(
844 getattr(call_obj, '__doc__', ''))
844 getattr(call_obj, '__doc__', ''))
845
845
846 _keeps = (inspect.Parameter.KEYWORD_ONLY,
846 _keeps = (inspect.Parameter.KEYWORD_ONLY,
847 inspect.Parameter.POSITIONAL_OR_KEYWORD)
847 inspect.Parameter.POSITIONAL_OR_KEYWORD)
848
848
849 try:
849 try:
850 sig = inspect.signature(call_obj)
850 sig = inspect.signature(call_obj)
851 ret.extend(k for k, v in sig.parameters.items() if
851 ret.extend(k for k, v in sig.parameters.items() if
852 v.kind in _keeps)
852 v.kind in _keeps)
853 except ValueError:
853 except ValueError:
854 pass
854 pass
855
855
856 return list(set(ret))
856 return list(set(ret))
857
857
858 def python_func_kw_matches(self,text):
858 def python_func_kw_matches(self,text):
859 """Match named parameters (kwargs) of the last open function"""
859 """Match named parameters (kwargs) of the last open function"""
860
860
861 if "." in text: # a parameter cannot be dotted
861 if "." in text: # a parameter cannot be dotted
862 return []
862 return []
863 try: regexp = self.__funcParamsRegex
863 try: regexp = self.__funcParamsRegex
864 except AttributeError:
864 except AttributeError:
865 regexp = self.__funcParamsRegex = re.compile(r'''
865 regexp = self.__funcParamsRegex = re.compile(r'''
866 '.*?(?<!\\)' | # single quoted strings or
866 '.*?(?<!\\)' | # single quoted strings or
867 ".*?(?<!\\)" | # double quoted strings or
867 ".*?(?<!\\)" | # double quoted strings or
868 \w+ | # identifier
868 \w+ | # identifier
869 \S # other characters
869 \S # other characters
870 ''', re.VERBOSE | re.DOTALL)
870 ''', re.VERBOSE | re.DOTALL)
871 # 1. find the nearest identifier that comes before an unclosed
871 # 1. find the nearest identifier that comes before an unclosed
872 # parenthesis before the cursor
872 # parenthesis before the cursor
873 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
873 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
874 tokens = regexp.findall(self.text_until_cursor)
874 tokens = regexp.findall(self.text_until_cursor)
875 iterTokens = reversed(tokens); openPar = 0
875 iterTokens = reversed(tokens); openPar = 0
876
876
877 for token in iterTokens:
877 for token in iterTokens:
878 if token == ')':
878 if token == ')':
879 openPar -= 1
879 openPar -= 1
880 elif token == '(':
880 elif token == '(':
881 openPar += 1
881 openPar += 1
882 if openPar > 0:
882 if openPar > 0:
883 # found the last unclosed parenthesis
883 # found the last unclosed parenthesis
884 break
884 break
885 else:
885 else:
886 return []
886 return []
887 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
887 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
888 ids = []
888 ids = []
889 isId = re.compile(r'\w+$').match
889 isId = re.compile(r'\w+$').match
890
890
891 while True:
891 while True:
892 try:
892 try:
893 ids.append(next(iterTokens))
893 ids.append(next(iterTokens))
894 if not isId(ids[-1]):
894 if not isId(ids[-1]):
895 ids.pop(); break
895 ids.pop(); break
896 if not next(iterTokens) == '.':
896 if not next(iterTokens) == '.':
897 break
897 break
898 except StopIteration:
898 except StopIteration:
899 break
899 break
900
900
901 # Find all named arguments already assigned to, as to avoid suggesting
901 # Find all named arguments already assigned to, as to avoid suggesting
902 # them again
902 # them again
903 usedNamedArgs = set()
903 usedNamedArgs = set()
904 par_level = -1
904 par_level = -1
905 for token, next_token in zip(tokens, tokens[1:]):
905 for token, next_token in zip(tokens, tokens[1:]):
906 if token == '(':
906 if token == '(':
907 par_level += 1
907 par_level += 1
908 elif token == ')':
908 elif token == ')':
909 par_level -= 1
909 par_level -= 1
910
910
911 if par_level != 0:
911 if par_level != 0:
912 continue
912 continue
913
913
914 if next_token != '=':
914 if next_token != '=':
915 continue
915 continue
916
916
917 usedNamedArgs.add(token)
917 usedNamedArgs.add(token)
918
918
919 # lookup the candidate callable matches either using global_matches
919 # lookup the candidate callable matches either using global_matches
920 # or attr_matches for dotted names
920 # or attr_matches for dotted names
921 if len(ids) == 1:
921 if len(ids) == 1:
922 callableMatches = self.global_matches(ids[0])
922 callableMatches = self.global_matches(ids[0])
923 else:
923 else:
924 callableMatches = self.attr_matches('.'.join(ids[::-1]))
924 callableMatches = self.attr_matches('.'.join(ids[::-1]))
925 argMatches = []
925 argMatches = []
926 for callableMatch in callableMatches:
926 for callableMatch in callableMatches:
927 try:
927 try:
928 namedArgs = self._default_arguments(eval(callableMatch,
928 namedArgs = self._default_arguments(eval(callableMatch,
929 self.namespace))
929 self.namespace))
930 except:
930 except:
931 continue
931 continue
932
932
933 # Remove used named arguments from the list, no need to show twice
933 # Remove used named arguments from the list, no need to show twice
934 for namedArg in set(namedArgs) - usedNamedArgs:
934 for namedArg in set(namedArgs) - usedNamedArgs:
935 if namedArg.startswith(text):
935 if namedArg.startswith(text):
936 argMatches.append(u"%s=" %namedArg)
936 argMatches.append(u"%s=" %namedArg)
937 return argMatches
937 return argMatches
938
938
939 def dict_key_matches(self, text):
939 def dict_key_matches(self, text):
940 "Match string keys in a dictionary, after e.g. 'foo[' "
940 "Match string keys in a dictionary, after e.g. 'foo[' "
941 def get_keys(obj):
941 def get_keys(obj):
942 # Objects can define their own completions by defining an
942 # Objects can define their own completions by defining an
943 # _ipy_key_completions_() method.
943 # _ipy_key_completions_() method.
944 method = get_real_method(obj, '_ipython_key_completions_')
944 method = get_real_method(obj, '_ipython_key_completions_')
945 if method is not None:
945 if method is not None:
946 return method()
946 return method()
947
947
948 # Special case some common in-memory dict-like types
948 # Special case some common in-memory dict-like types
949 if isinstance(obj, dict) or\
949 if isinstance(obj, dict) or\
950 _safe_isinstance(obj, 'pandas', 'DataFrame'):
950 _safe_isinstance(obj, 'pandas', 'DataFrame'):
951 try:
951 try:
952 return list(obj.keys())
952 return list(obj.keys())
953 except Exception:
953 except Exception:
954 return []
954 return []
955 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
955 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
956 _safe_isinstance(obj, 'numpy', 'void'):
956 _safe_isinstance(obj, 'numpy', 'void'):
957 return obj.dtype.names or []
957 return obj.dtype.names or []
958 return []
958 return []
959
959
960 try:
960 try:
961 regexps = self.__dict_key_regexps
961 regexps = self.__dict_key_regexps
962 except AttributeError:
962 except AttributeError:
963 dict_key_re_fmt = r'''(?x)
963 dict_key_re_fmt = r'''(?x)
964 ( # match dict-referring expression wrt greedy setting
964 ( # match dict-referring expression wrt greedy setting
965 %s
965 %s
966 )
966 )
967 \[ # open bracket
967 \[ # open bracket
968 \s* # and optional whitespace
968 \s* # and optional whitespace
969 ([uUbB]? # string prefix (r not handled)
969 ([uUbB]? # string prefix (r not handled)
970 (?: # unclosed string
970 (?: # unclosed string
971 '(?:[^']|(?<!\\)\\')*
971 '(?:[^']|(?<!\\)\\')*
972 |
972 |
973 "(?:[^"]|(?<!\\)\\")*
973 "(?:[^"]|(?<!\\)\\")*
974 )
974 )
975 )?
975 )?
976 $
976 $
977 '''
977 '''
978 regexps = self.__dict_key_regexps = {
978 regexps = self.__dict_key_regexps = {
979 False: re.compile(dict_key_re_fmt % '''
979 False: re.compile(dict_key_re_fmt % '''
980 # identifiers separated by .
980 # identifiers separated by .
981 (?!\d)\w+
981 (?!\d)\w+
982 (?:\.(?!\d)\w+)*
982 (?:\.(?!\d)\w+)*
983 '''),
983 '''),
984 True: re.compile(dict_key_re_fmt % '''
984 True: re.compile(dict_key_re_fmt % '''
985 .+
985 .+
986 ''')
986 ''')
987 }
987 }
988
988
989 match = regexps[self.greedy].search(self.text_until_cursor)
989 match = regexps[self.greedy].search(self.text_until_cursor)
990 if match is None:
990 if match is None:
991 return []
991 return []
992
992
993 expr, prefix = match.groups()
993 expr, prefix = match.groups()
994 try:
994 try:
995 obj = eval(expr, self.namespace)
995 obj = eval(expr, self.namespace)
996 except Exception:
996 except Exception:
997 try:
997 try:
998 obj = eval(expr, self.global_namespace)
998 obj = eval(expr, self.global_namespace)
999 except Exception:
999 except Exception:
1000 return []
1000 return []
1001
1001
1002 keys = get_keys(obj)
1002 keys = get_keys(obj)
1003 if not keys:
1003 if not keys:
1004 return keys
1004 return keys
1005 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1005 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1006 if not matches:
1006 if not matches:
1007 return matches
1007 return matches
1008
1008
1009 # get the cursor position of
1009 # get the cursor position of
1010 # - the text being completed
1010 # - the text being completed
1011 # - the start of the key text
1011 # - the start of the key text
1012 # - the start of the completion
1012 # - the start of the completion
1013 text_start = len(self.text_until_cursor) - len(text)
1013 text_start = len(self.text_until_cursor) - len(text)
1014 if prefix:
1014 if prefix:
1015 key_start = match.start(2)
1015 key_start = match.start(2)
1016 completion_start = key_start + token_offset
1016 completion_start = key_start + token_offset
1017 else:
1017 else:
1018 key_start = completion_start = match.end()
1018 key_start = completion_start = match.end()
1019
1019
1020 # grab the leading prefix, to make sure all completions start with `text`
1020 # grab the leading prefix, to make sure all completions start with `text`
1021 if text_start > key_start:
1021 if text_start > key_start:
1022 leading = ''
1022 leading = ''
1023 else:
1023 else:
1024 leading = text[text_start:completion_start]
1024 leading = text[text_start:completion_start]
1025
1025
1026 # the index of the `[` character
1026 # the index of the `[` character
1027 bracket_idx = match.end(1)
1027 bracket_idx = match.end(1)
1028
1028
1029 # append closing quote and bracket as appropriate
1029 # append closing quote and bracket as appropriate
1030 # this is *not* appropriate if the opening quote or bracket is outside
1030 # this is *not* appropriate if the opening quote or bracket is outside
1031 # the text given to this method
1031 # the text given to this method
1032 suf = ''
1032 suf = ''
1033 continuation = self.line_buffer[len(self.text_until_cursor):]
1033 continuation = self.line_buffer[len(self.text_until_cursor):]
1034 if key_start > text_start and closing_quote:
1034 if key_start > text_start and closing_quote:
1035 # quotes were opened inside text, maybe close them
1035 # quotes were opened inside text, maybe close them
1036 if continuation.startswith(closing_quote):
1036 if continuation.startswith(closing_quote):
1037 continuation = continuation[len(closing_quote):]
1037 continuation = continuation[len(closing_quote):]
1038 else:
1038 else:
1039 suf += closing_quote
1039 suf += closing_quote
1040 if bracket_idx > text_start:
1040 if bracket_idx > text_start:
1041 # brackets were opened inside text, maybe close them
1041 # brackets were opened inside text, maybe close them
1042 if not continuation.startswith(']'):
1042 if not continuation.startswith(']'):
1043 suf += ']'
1043 suf += ']'
1044
1044
1045 return [leading + k + suf for k in matches]
1045 return [leading + k + suf for k in matches]
1046
1046
1047 def unicode_name_matches(self, text):
1047 def unicode_name_matches(self, text):
1048 u"""Match Latex-like syntax for unicode characters base
1048 u"""Match Latex-like syntax for unicode characters base
1049 on the name of the character.
1049 on the name of the character.
1050
1050
1051 This does \\GREEK SMALL LETTER ETA -> Ξ·
1051 This does \\GREEK SMALL LETTER ETA -> Ξ·
1052
1052
1053 Works only on valid python 3 identifier, or on combining characters that
1053 Works only on valid python 3 identifier, or on combining characters that
1054 will combine to form a valid identifier.
1054 will combine to form a valid identifier.
1055
1055
1056 Used on Python 3 only.
1056 Used on Python 3 only.
1057 """
1057 """
1058 slashpos = text.rfind('\\')
1058 slashpos = text.rfind('\\')
1059 if slashpos > -1:
1059 if slashpos > -1:
1060 s = text[slashpos+1:]
1060 s = text[slashpos+1:]
1061 try :
1061 try :
1062 unic = unicodedata.lookup(s)
1062 unic = unicodedata.lookup(s)
1063 # allow combining chars
1063 # allow combining chars
1064 if ('a'+unic).isidentifier():
1064 if ('a'+unic).isidentifier():
1065 return '\\'+s,[unic]
1065 return '\\'+s,[unic]
1066 except KeyError:
1066 except KeyError:
1067 pass
1067 pass
1068 return u'', []
1068 return u'', []
1069
1069
1070
1070
1071
1071
1072
1072
1073 def latex_matches(self, text):
1073 def latex_matches(self, text):
1074 u"""Match Latex syntax for unicode characters.
1074 u"""Match Latex syntax for unicode characters.
1075
1075
1076 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1076 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1077
1077
1078 Used on Python 3 only.
1078 Used on Python 3 only.
1079 """
1079 """
1080 slashpos = text.rfind('\\')
1080 slashpos = text.rfind('\\')
1081 if slashpos > -1:
1081 if slashpos > -1:
1082 s = text[slashpos:]
1082 s = text[slashpos:]
1083 if s in latex_symbols:
1083 if s in latex_symbols:
1084 # Try to complete a full latex symbol to unicode
1084 # Try to complete a full latex symbol to unicode
1085 # \\alpha -> Ξ±
1085 # \\alpha -> Ξ±
1086 return s, [latex_symbols[s]]
1086 return s, [latex_symbols[s]]
1087 else:
1087 else:
1088 # If a user has partially typed a latex symbol, give them
1088 # If a user has partially typed a latex symbol, give them
1089 # a full list of options \al -> [\aleph, \alpha]
1089 # a full list of options \al -> [\aleph, \alpha]
1090 matches = [k for k in latex_symbols if k.startswith(s)]
1090 matches = [k for k in latex_symbols if k.startswith(s)]
1091 return s, matches
1091 return s, matches
1092 return u'', []
1092 return u'', []
1093
1093
1094 def dispatch_custom_completer(self, text):
1094 def dispatch_custom_completer(self, text):
1095 if not self.custom_completers:
1095 if not self.custom_completers:
1096 return
1096 return
1097
1097
1098 line = self.line_buffer
1098 line = self.line_buffer
1099 if not line.strip():
1099 if not line.strip():
1100 return None
1100 return None
1101
1101
1102 # Create a little structure to pass all the relevant information about
1102 # Create a little structure to pass all the relevant information about
1103 # the current completion to any custom completer.
1103 # the current completion to any custom completer.
1104 event = Bunch()
1104 event = Bunch()
1105 event.line = line
1105 event.line = line
1106 event.symbol = text
1106 event.symbol = text
1107 cmd = line.split(None,1)[0]
1107 cmd = line.split(None,1)[0]
1108 event.command = cmd
1108 event.command = cmd
1109 event.text_until_cursor = self.text_until_cursor
1109 event.text_until_cursor = self.text_until_cursor
1110
1110
1111 # for foo etc, try also to find completer for %foo
1111 # for foo etc, try also to find completer for %foo
1112 if not cmd.startswith(self.magic_escape):
1112 if not cmd.startswith(self.magic_escape):
1113 try_magic = self.custom_completers.s_matches(
1113 try_magic = self.custom_completers.s_matches(
1114 self.magic_escape + cmd)
1114 self.magic_escape + cmd)
1115 else:
1115 else:
1116 try_magic = []
1116 try_magic = []
1117
1117
1118 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1118 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1119 try_magic,
1119 try_magic,
1120 self.custom_completers.flat_matches(self.text_until_cursor)):
1120 self.custom_completers.flat_matches(self.text_until_cursor)):
1121 try:
1121 try:
1122 res = c(event)
1122 res = c(event)
1123 if res:
1123 if res:
1124 # first, try case sensitive match
1124 # first, try case sensitive match
1125 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1125 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1126 if withcase:
1126 if withcase:
1127 return withcase
1127 return withcase
1128 # if none, then case insensitive ones are ok too
1128 # if none, then case insensitive ones are ok too
1129 text_low = text.lower()
1129 text_low = text.lower()
1130 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1130 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1131 except TryNext:
1131 except TryNext:
1132 pass
1132 pass
1133
1133
1134 return None
1134 return None
1135
1135
1136 @_strip_single_trailing_space
1136 @_strip_single_trailing_space
1137 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1137 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1138 """Find completions for the given text and line context.
1138 """Find completions for the given text and line context.
1139
1139
1140 Note that both the text and the line_buffer are optional, but at least
1140 Note that both the text and the line_buffer are optional, but at least
1141 one of them must be given.
1141 one of them must be given.
1142
1142
1143 Parameters
1143 Parameters
1144 ----------
1144 ----------
1145 text : string, optional
1145 text : string, optional
1146 Text to perform the completion on. If not given, the line buffer
1146 Text to perform the completion on. If not given, the line buffer
1147 is split using the instance's CompletionSplitter object.
1147 is split using the instance's CompletionSplitter object.
1148
1148
1149 line_buffer : string, optional
1149 line_buffer : string, optional
1150 If not given, the completer attempts to obtain the current line
1150 If not given, the completer attempts to obtain the current line
1151 buffer via readline. This keyword allows clients which are
1151 buffer via readline. This keyword allows clients which are
1152 requesting for text completions in non-readline contexts to inform
1152 requesting for text completions in non-readline contexts to inform
1153 the completer of the entire text.
1153 the completer of the entire text.
1154
1154
1155 cursor_pos : int, optional
1155 cursor_pos : int, optional
1156 Index of the cursor in the full line buffer. Should be provided by
1156 Index of the cursor in the full line buffer. Should be provided by
1157 remote frontends where kernel has no access to frontend state.
1157 remote frontends where kernel has no access to frontend state.
1158
1158
1159 Returns
1159 Returns
1160 -------
1160 -------
1161 text : str
1161 text : str
1162 Text that was actually used in the completion.
1162 Text that was actually used in the completion.
1163
1163
1164 matches : list
1164 matches : list
1165 A list of completion matches.
1165 A list of completion matches.
1166 """
1166 """
1167 # if the cursor position isn't given, the only sane assumption we can
1167 # if the cursor position isn't given, the only sane assumption we can
1168 # make is that it's at the end of the line (the common case)
1168 # make is that it's at the end of the line (the common case)
1169 if cursor_pos is None:
1169 if cursor_pos is None:
1170 cursor_pos = len(line_buffer) if text is None else len(text)
1170 cursor_pos = len(line_buffer) if text is None else len(text)
1171
1171
1172 if self.use_main_ns:
1172 if self.use_main_ns:
1173 self.namespace = __main__.__dict__
1173 self.namespace = __main__.__dict__
1174
1174
1175 if PY3:
1176
1177 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1175 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1178 latex_text, latex_matches = self.latex_matches(base_text)
1176 latex_text, latex_matches = self.latex_matches(base_text)
1179 if latex_matches:
1177 if latex_matches:
1180 return latex_text, latex_matches
1178 return latex_text, latex_matches
1181 name_text = ''
1179 name_text = ''
1182 name_matches = []
1180 name_matches = []
1183 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1181 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1184 name_text, name_matches = meth(base_text)
1182 name_text, name_matches = meth(base_text)
1185 if name_text:
1183 if name_text:
1186 return name_text, name_matches
1184 return name_text, name_matches
1187
1185
1188 # if text is either None or an empty string, rely on the line buffer
1186 # if text is either None or an empty string, rely on the line buffer
1189 if not text:
1187 if not text:
1190 text = self.splitter.split_line(line_buffer, cursor_pos)
1188 text = self.splitter.split_line(line_buffer, cursor_pos)
1191
1189
1192 # If no line buffer is given, assume the input text is all there was
1190 # If no line buffer is given, assume the input text is all there was
1193 if line_buffer is None:
1191 if line_buffer is None:
1194 line_buffer = text
1192 line_buffer = text
1195
1193
1196 self.line_buffer = line_buffer
1194 self.line_buffer = line_buffer
1197 self.text_until_cursor = self.line_buffer[:cursor_pos]
1195 self.text_until_cursor = self.line_buffer[:cursor_pos]
1198
1196
1199 # Start with a clean slate of completions
1197 # Start with a clean slate of completions
1200 self.matches[:] = []
1198 self.matches[:] = []
1201 custom_res = self.dispatch_custom_completer(text)
1199 custom_res = self.dispatch_custom_completer(text)
1202 if custom_res is not None:
1200 if custom_res is not None:
1203 # did custom completers produce something?
1201 # did custom completers produce something?
1204 self.matches = custom_res
1202 self.matches = custom_res
1205 else:
1203 else:
1206 # Extend the list of completions with the results of each
1204 # Extend the list of completions with the results of each
1207 # matcher, so we return results to the user from all
1205 # matcher, so we return results to the user from all
1208 # namespaces.
1206 # namespaces.
1209 if self.merge_completions:
1207 if self.merge_completions:
1210 self.matches = []
1208 self.matches = []
1211 for matcher in self.matchers:
1209 for matcher in self.matchers:
1212 try:
1210 try:
1213 self.matches.extend(matcher(text))
1211 self.matches.extend(matcher(text))
1214 except:
1212 except:
1215 # Show the ugly traceback if the matcher causes an
1213 # Show the ugly traceback if the matcher causes an
1216 # exception, but do NOT crash the kernel!
1214 # exception, but do NOT crash the kernel!
1217 sys.excepthook(*sys.exc_info())
1215 sys.excepthook(*sys.exc_info())
1218 else:
1216 else:
1219 for matcher in self.matchers:
1217 for matcher in self.matchers:
1220 self.matches = matcher(text)
1218 self.matches = matcher(text)
1221 if self.matches:
1219 if self.matches:
1222 break
1220 break
1223 # FIXME: we should extend our api to return a dict with completions for
1221 # FIXME: we should extend our api to return a dict with completions for
1224 # different types of objects. The rlcomplete() method could then
1222 # different types of objects. The rlcomplete() method could then
1225 # simply collapse the dict into a list for readline, but we'd have
1223 # simply collapse the dict into a list for readline, but we'd have
1226 # richer completion semantics in other evironments.
1224 # richer completion semantics in other evironments.
1227 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1225 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1228
1226
1229 return text, self.matches
1227 return text, self.matches
@@ -1,537 +1,532 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 from io import StringIO
9
10
10 from IPython.core.splitinput import LineInfo
11 from IPython.core.splitinput import LineInfo
11 from IPython.utils import tokenize2
12 from IPython.utils import tokenize2
12 from IPython.utils.py3compat import PY3
13 from IPython.utils.tokenize2 import generate_tokens, untokenize, TokenError
13 from IPython.utils.tokenize2 import generate_tokens, untokenize, TokenError
14
14
15 if PY3:
16 from io import StringIO
17 else:
18 from StringIO import StringIO
19
20 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
21 # Globals
16 # Globals
22 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
23
18
24 # The escape sequences that define the syntax transformations IPython will
19 # The escape sequences that define the syntax transformations IPython will
25 # apply to user input. These can NOT be just changed here: many regular
20 # apply to user input. These can NOT be just changed here: many regular
26 # expressions and other parts of the code may use their hardcoded values, and
21 # expressions and other parts of the code may use their hardcoded values, and
27 # for all intents and purposes they constitute the 'IPython syntax', so they
22 # for all intents and purposes they constitute the 'IPython syntax', so they
28 # should be considered fixed.
23 # should be considered fixed.
29
24
30 ESC_SHELL = '!' # Send line to underlying system shell
25 ESC_SHELL = '!' # Send line to underlying system shell
31 ESC_SH_CAP = '!!' # Send line to system shell and capture output
26 ESC_SH_CAP = '!!' # Send line to system shell and capture output
32 ESC_HELP = '?' # Find information about object
27 ESC_HELP = '?' # Find information about object
33 ESC_HELP2 = '??' # Find extra-detailed information about object
28 ESC_HELP2 = '??' # Find extra-detailed information about object
34 ESC_MAGIC = '%' # Call magic function
29 ESC_MAGIC = '%' # Call magic function
35 ESC_MAGIC2 = '%%' # Call cell-magic function
30 ESC_MAGIC2 = '%%' # Call cell-magic function
36 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
31 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
37 ESC_QUOTE2 = ';' # Quote all args as a single string, call
32 ESC_QUOTE2 = ';' # Quote all args as a single string, call
38 ESC_PAREN = '/' # Call first argument with rest of line as arguments
33 ESC_PAREN = '/' # Call first argument with rest of line as arguments
39
34
40 ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
35 ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
41 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
36 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
42 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
37 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
43
38
44
39
45 class InputTransformer(metaclass=abc.ABCMeta):
40 class InputTransformer(metaclass=abc.ABCMeta):
46 """Abstract base class for line-based input transformers."""
41 """Abstract base class for line-based input transformers."""
47
42
48 @abc.abstractmethod
43 @abc.abstractmethod
49 def push(self, line):
44 def push(self, line):
50 """Send a line of input to the transformer, returning the transformed
45 """Send a line of input to the transformer, returning the transformed
51 input or None if the transformer is waiting for more input.
46 input or None if the transformer is waiting for more input.
52
47
53 Must be overridden by subclasses.
48 Must be overridden by subclasses.
54
49
55 Implementations may raise ``SyntaxError`` if the input is invalid. No
50 Implementations may raise ``SyntaxError`` if the input is invalid. No
56 other exceptions may be raised.
51 other exceptions may be raised.
57 """
52 """
58 pass
53 pass
59
54
60 @abc.abstractmethod
55 @abc.abstractmethod
61 def reset(self):
56 def reset(self):
62 """Return, transformed any lines that the transformer has accumulated,
57 """Return, transformed any lines that the transformer has accumulated,
63 and reset its internal state.
58 and reset its internal state.
64
59
65 Must be overridden by subclasses.
60 Must be overridden by subclasses.
66 """
61 """
67 pass
62 pass
68
63
69 @classmethod
64 @classmethod
70 def wrap(cls, func):
65 def wrap(cls, func):
71 """Can be used by subclasses as a decorator, to return a factory that
66 """Can be used by subclasses as a decorator, to return a factory that
72 will allow instantiation with the decorated object.
67 will allow instantiation with the decorated object.
73 """
68 """
74 @functools.wraps(func)
69 @functools.wraps(func)
75 def transformer_factory(**kwargs):
70 def transformer_factory(**kwargs):
76 return cls(func, **kwargs)
71 return cls(func, **kwargs)
77
72
78 return transformer_factory
73 return transformer_factory
79
74
80 class StatelessInputTransformer(InputTransformer):
75 class StatelessInputTransformer(InputTransformer):
81 """Wrapper for a stateless input transformer implemented as a function."""
76 """Wrapper for a stateless input transformer implemented as a function."""
82 def __init__(self, func):
77 def __init__(self, func):
83 self.func = func
78 self.func = func
84
79
85 def __repr__(self):
80 def __repr__(self):
86 return "StatelessInputTransformer(func={0!r})".format(self.func)
81 return "StatelessInputTransformer(func={0!r})".format(self.func)
87
82
88 def push(self, line):
83 def push(self, line):
89 """Send a line of input to the transformer, returning the
84 """Send a line of input to the transformer, returning the
90 transformed input."""
85 transformed input."""
91 return self.func(line)
86 return self.func(line)
92
87
93 def reset(self):
88 def reset(self):
94 """No-op - exists for compatibility."""
89 """No-op - exists for compatibility."""
95 pass
90 pass
96
91
97 class CoroutineInputTransformer(InputTransformer):
92 class CoroutineInputTransformer(InputTransformer):
98 """Wrapper for an input transformer implemented as a coroutine."""
93 """Wrapper for an input transformer implemented as a coroutine."""
99 def __init__(self, coro, **kwargs):
94 def __init__(self, coro, **kwargs):
100 # Prime it
95 # Prime it
101 self.coro = coro(**kwargs)
96 self.coro = coro(**kwargs)
102 next(self.coro)
97 next(self.coro)
103
98
104 def __repr__(self):
99 def __repr__(self):
105 return "CoroutineInputTransformer(coro={0!r})".format(self.coro)
100 return "CoroutineInputTransformer(coro={0!r})".format(self.coro)
106
101
107 def push(self, line):
102 def push(self, line):
108 """Send a line of input to the transformer, returning the
103 """Send a line of input to the transformer, returning the
109 transformed input or None if the transformer is waiting for more
104 transformed input or None if the transformer is waiting for more
110 input.
105 input.
111 """
106 """
112 return self.coro.send(line)
107 return self.coro.send(line)
113
108
114 def reset(self):
109 def reset(self):
115 """Return, transformed any lines that the transformer has
110 """Return, transformed any lines that the transformer has
116 accumulated, and reset its internal state.
111 accumulated, and reset its internal state.
117 """
112 """
118 return self.coro.send(None)
113 return self.coro.send(None)
119
114
120 class TokenInputTransformer(InputTransformer):
115 class TokenInputTransformer(InputTransformer):
121 """Wrapper for a token-based input transformer.
116 """Wrapper for a token-based input transformer.
122
117
123 func should accept a list of tokens (5-tuples, see tokenize docs), and
118 func should accept a list of tokens (5-tuples, see tokenize docs), and
124 return an iterable which can be passed to tokenize.untokenize().
119 return an iterable which can be passed to tokenize.untokenize().
125 """
120 """
126 def __init__(self, func):
121 def __init__(self, func):
127 self.func = func
122 self.func = func
128 self.current_line = ""
123 self.current_line = ""
129 self.line_used = False
124 self.line_used = False
130 self.reset_tokenizer()
125 self.reset_tokenizer()
131
126
132 def reset_tokenizer(self):
127 def reset_tokenizer(self):
133 self.tokenizer = generate_tokens(self.get_line)
128 self.tokenizer = generate_tokens(self.get_line)
134
129
135 def get_line(self):
130 def get_line(self):
136 if self.line_used:
131 if self.line_used:
137 raise TokenError
132 raise TokenError
138 self.line_used = True
133 self.line_used = True
139 return self.current_line
134 return self.current_line
140
135
141 def push(self, line):
136 def push(self, line):
142 self.current_line += line + "\n"
137 self.current_line += line + "\n"
143 if self.current_line.isspace():
138 if self.current_line.isspace():
144 return self.reset()
139 return self.reset()
145
140
146 self.line_used = False
141 self.line_used = False
147 tokens = []
142 tokens = []
148 stop_at_NL = False
143 stop_at_NL = False
149 try:
144 try:
150 for intok in self.tokenizer:
145 for intok in self.tokenizer:
151 tokens.append(intok)
146 tokens.append(intok)
152 t = intok[0]
147 t = intok[0]
153 if t == tokenize2.NEWLINE or (stop_at_NL and t == tokenize2.NL):
148 if t == tokenize2.NEWLINE or (stop_at_NL and t == tokenize2.NL):
154 # Stop before we try to pull a line we don't have yet
149 # Stop before we try to pull a line we don't have yet
155 break
150 break
156 elif t == tokenize2.ERRORTOKEN:
151 elif t == tokenize2.ERRORTOKEN:
157 stop_at_NL = True
152 stop_at_NL = True
158 except TokenError:
153 except TokenError:
159 # Multi-line statement - stop and try again with the next line
154 # Multi-line statement - stop and try again with the next line
160 self.reset_tokenizer()
155 self.reset_tokenizer()
161 return None
156 return None
162
157
163 return self.output(tokens)
158 return self.output(tokens)
164
159
165 def output(self, tokens):
160 def output(self, tokens):
166 self.current_line = ""
161 self.current_line = ""
167 self.reset_tokenizer()
162 self.reset_tokenizer()
168 return untokenize(self.func(tokens)).rstrip('\n')
163 return untokenize(self.func(tokens)).rstrip('\n')
169
164
170 def reset(self):
165 def reset(self):
171 l = self.current_line
166 l = self.current_line
172 self.current_line = ""
167 self.current_line = ""
173 self.reset_tokenizer()
168 self.reset_tokenizer()
174 if l:
169 if l:
175 return l.rstrip('\n')
170 return l.rstrip('\n')
176
171
177 class assemble_python_lines(TokenInputTransformer):
172 class assemble_python_lines(TokenInputTransformer):
178 def __init__(self):
173 def __init__(self):
179 super(assemble_python_lines, self).__init__(None)
174 super(assemble_python_lines, self).__init__(None)
180
175
181 def output(self, tokens):
176 def output(self, tokens):
182 return self.reset()
177 return self.reset()
183
178
184 @CoroutineInputTransformer.wrap
179 @CoroutineInputTransformer.wrap
185 def assemble_logical_lines():
180 def assemble_logical_lines():
186 """Join lines following explicit line continuations (\)"""
181 """Join lines following explicit line continuations (\)"""
187 line = ''
182 line = ''
188 while True:
183 while True:
189 line = (yield line)
184 line = (yield line)
190 if not line or line.isspace():
185 if not line or line.isspace():
191 continue
186 continue
192
187
193 parts = []
188 parts = []
194 while line is not None:
189 while line is not None:
195 if line.endswith('\\') and (not has_comment(line)):
190 if line.endswith('\\') and (not has_comment(line)):
196 parts.append(line[:-1])
191 parts.append(line[:-1])
197 line = (yield None) # Get another line
192 line = (yield None) # Get another line
198 else:
193 else:
199 parts.append(line)
194 parts.append(line)
200 break
195 break
201
196
202 # Output
197 # Output
203 line = ''.join(parts)
198 line = ''.join(parts)
204
199
205 # Utilities
200 # Utilities
206 def _make_help_call(target, esc, lspace, next_input=None):
201 def _make_help_call(target, esc, lspace, next_input=None):
207 """Prepares a pinfo(2)/psearch call from a target name and the escape
202 """Prepares a pinfo(2)/psearch call from a target name and the escape
208 (i.e. ? or ??)"""
203 (i.e. ? or ??)"""
209 method = 'pinfo2' if esc == '??' \
204 method = 'pinfo2' if esc == '??' \
210 else 'psearch' if '*' in target \
205 else 'psearch' if '*' in target \
211 else 'pinfo'
206 else 'pinfo'
212 arg = " ".join([method, target])
207 arg = " ".join([method, target])
213 if next_input is None:
208 if next_input is None:
214 return '%sget_ipython().magic(%r)' % (lspace, arg)
209 return '%sget_ipython().magic(%r)' % (lspace, arg)
215 else:
210 else:
216 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
211 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
217 (lspace, next_input, arg)
212 (lspace, next_input, arg)
218
213
219 # These define the transformations for the different escape characters.
214 # These define the transformations for the different escape characters.
220 def _tr_system(line_info):
215 def _tr_system(line_info):
221 "Translate lines escaped with: !"
216 "Translate lines escaped with: !"
222 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
217 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
223 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
218 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
224
219
225 def _tr_system2(line_info):
220 def _tr_system2(line_info):
226 "Translate lines escaped with: !!"
221 "Translate lines escaped with: !!"
227 cmd = line_info.line.lstrip()[2:]
222 cmd = line_info.line.lstrip()[2:]
228 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
223 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
229
224
230 def _tr_help(line_info):
225 def _tr_help(line_info):
231 "Translate lines escaped with: ?/??"
226 "Translate lines escaped with: ?/??"
232 # A naked help line should just fire the intro help screen
227 # A naked help line should just fire the intro help screen
233 if not line_info.line[1:]:
228 if not line_info.line[1:]:
234 return 'get_ipython().show_usage()'
229 return 'get_ipython().show_usage()'
235
230
236 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
231 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
237
232
238 def _tr_magic(line_info):
233 def _tr_magic(line_info):
239 "Translate lines escaped with: %"
234 "Translate lines escaped with: %"
240 tpl = '%sget_ipython().magic(%r)'
235 tpl = '%sget_ipython().magic(%r)'
241 if line_info.line.startswith(ESC_MAGIC2):
236 if line_info.line.startswith(ESC_MAGIC2):
242 return line_info.line
237 return line_info.line
243 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
238 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
244 return tpl % (line_info.pre, cmd)
239 return tpl % (line_info.pre, cmd)
245
240
246 def _tr_quote(line_info):
241 def _tr_quote(line_info):
247 "Translate lines escaped with: ,"
242 "Translate lines escaped with: ,"
248 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
243 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
249 '", "'.join(line_info.the_rest.split()) )
244 '", "'.join(line_info.the_rest.split()) )
250
245
251 def _tr_quote2(line_info):
246 def _tr_quote2(line_info):
252 "Translate lines escaped with: ;"
247 "Translate lines escaped with: ;"
253 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
248 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
254 line_info.the_rest)
249 line_info.the_rest)
255
250
256 def _tr_paren(line_info):
251 def _tr_paren(line_info):
257 "Translate lines escaped with: /"
252 "Translate lines escaped with: /"
258 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
253 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
259 ", ".join(line_info.the_rest.split()))
254 ", ".join(line_info.the_rest.split()))
260
255
261 tr = { ESC_SHELL : _tr_system,
256 tr = { ESC_SHELL : _tr_system,
262 ESC_SH_CAP : _tr_system2,
257 ESC_SH_CAP : _tr_system2,
263 ESC_HELP : _tr_help,
258 ESC_HELP : _tr_help,
264 ESC_HELP2 : _tr_help,
259 ESC_HELP2 : _tr_help,
265 ESC_MAGIC : _tr_magic,
260 ESC_MAGIC : _tr_magic,
266 ESC_QUOTE : _tr_quote,
261 ESC_QUOTE : _tr_quote,
267 ESC_QUOTE2 : _tr_quote2,
262 ESC_QUOTE2 : _tr_quote2,
268 ESC_PAREN : _tr_paren }
263 ESC_PAREN : _tr_paren }
269
264
270 @StatelessInputTransformer.wrap
265 @StatelessInputTransformer.wrap
271 def escaped_commands(line):
266 def escaped_commands(line):
272 """Transform escaped commands - %magic, !system, ?help + various autocalls.
267 """Transform escaped commands - %magic, !system, ?help + various autocalls.
273 """
268 """
274 if not line or line.isspace():
269 if not line or line.isspace():
275 return line
270 return line
276 lineinf = LineInfo(line)
271 lineinf = LineInfo(line)
277 if lineinf.esc not in tr:
272 if lineinf.esc not in tr:
278 return line
273 return line
279
274
280 return tr[lineinf.esc](lineinf)
275 return tr[lineinf.esc](lineinf)
281
276
282 _initial_space_re = re.compile(r'\s*')
277 _initial_space_re = re.compile(r'\s*')
283
278
284 _help_end_re = re.compile(r"""(%{0,2}
279 _help_end_re = re.compile(r"""(%{0,2}
285 [a-zA-Z_*][\w*]* # Variable name
280 [a-zA-Z_*][\w*]* # Variable name
286 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
281 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
287 )
282 )
288 (\?\??)$ # ? or ??
283 (\?\??)$ # ? or ??
289 """,
284 """,
290 re.VERBOSE)
285 re.VERBOSE)
291
286
292 # Extra pseudotokens for multiline strings and data structures
287 # Extra pseudotokens for multiline strings and data structures
293 _MULTILINE_STRING = object()
288 _MULTILINE_STRING = object()
294 _MULTILINE_STRUCTURE = object()
289 _MULTILINE_STRUCTURE = object()
295
290
296 def _line_tokens(line):
291 def _line_tokens(line):
297 """Helper for has_comment and ends_in_comment_or_string."""
292 """Helper for has_comment and ends_in_comment_or_string."""
298 readline = StringIO(line).readline
293 readline = StringIO(line).readline
299 toktypes = set()
294 toktypes = set()
300 try:
295 try:
301 for t in generate_tokens(readline):
296 for t in generate_tokens(readline):
302 toktypes.add(t[0])
297 toktypes.add(t[0])
303 except TokenError as e:
298 except TokenError as e:
304 # There are only two cases where a TokenError is raised.
299 # There are only two cases where a TokenError is raised.
305 if 'multi-line string' in e.args[0]:
300 if 'multi-line string' in e.args[0]:
306 toktypes.add(_MULTILINE_STRING)
301 toktypes.add(_MULTILINE_STRING)
307 else:
302 else:
308 toktypes.add(_MULTILINE_STRUCTURE)
303 toktypes.add(_MULTILINE_STRUCTURE)
309 return toktypes
304 return toktypes
310
305
311 def has_comment(src):
306 def has_comment(src):
312 """Indicate whether an input line has (i.e. ends in, or is) a comment.
307 """Indicate whether an input line has (i.e. ends in, or is) a comment.
313
308
314 This uses tokenize, so it can distinguish comments from # inside strings.
309 This uses tokenize, so it can distinguish comments from # inside strings.
315
310
316 Parameters
311 Parameters
317 ----------
312 ----------
318 src : string
313 src : string
319 A single line input string.
314 A single line input string.
320
315
321 Returns
316 Returns
322 -------
317 -------
323 comment : bool
318 comment : bool
324 True if source has a comment.
319 True if source has a comment.
325 """
320 """
326 return (tokenize2.COMMENT in _line_tokens(src))
321 return (tokenize2.COMMENT in _line_tokens(src))
327
322
328 def ends_in_comment_or_string(src):
323 def ends_in_comment_or_string(src):
329 """Indicates whether or not an input line ends in a comment or within
324 """Indicates whether or not an input line ends in a comment or within
330 a multiline string.
325 a multiline string.
331
326
332 Parameters
327 Parameters
333 ----------
328 ----------
334 src : string
329 src : string
335 A single line input string.
330 A single line input string.
336
331
337 Returns
332 Returns
338 -------
333 -------
339 comment : bool
334 comment : bool
340 True if source ends in a comment or multiline string.
335 True if source ends in a comment or multiline string.
341 """
336 """
342 toktypes = _line_tokens(src)
337 toktypes = _line_tokens(src)
343 return (tokenize2.COMMENT in toktypes) or (_MULTILINE_STRING in toktypes)
338 return (tokenize2.COMMENT in toktypes) or (_MULTILINE_STRING in toktypes)
344
339
345
340
346 @StatelessInputTransformer.wrap
341 @StatelessInputTransformer.wrap
347 def help_end(line):
342 def help_end(line):
348 """Translate lines with ?/?? at the end"""
343 """Translate lines with ?/?? at the end"""
349 m = _help_end_re.search(line)
344 m = _help_end_re.search(line)
350 if m is None or ends_in_comment_or_string(line):
345 if m is None or ends_in_comment_or_string(line):
351 return line
346 return line
352 target = m.group(1)
347 target = m.group(1)
353 esc = m.group(3)
348 esc = m.group(3)
354 lspace = _initial_space_re.match(line).group(0)
349 lspace = _initial_space_re.match(line).group(0)
355
350
356 # If we're mid-command, put it back on the next prompt for the user.
351 # If we're mid-command, put it back on the next prompt for the user.
357 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
352 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
358
353
359 return _make_help_call(target, esc, lspace, next_input)
354 return _make_help_call(target, esc, lspace, next_input)
360
355
361
356
362 @CoroutineInputTransformer.wrap
357 @CoroutineInputTransformer.wrap
363 def cellmagic(end_on_blank_line=False):
358 def cellmagic(end_on_blank_line=False):
364 """Captures & transforms cell magics.
359 """Captures & transforms cell magics.
365
360
366 After a cell magic is started, this stores up any lines it gets until it is
361 After a cell magic is started, this stores up any lines it gets until it is
367 reset (sent None).
362 reset (sent None).
368 """
363 """
369 tpl = 'get_ipython().run_cell_magic(%r, %r, %r)'
364 tpl = 'get_ipython().run_cell_magic(%r, %r, %r)'
370 cellmagic_help_re = re.compile('%%\w+\?')
365 cellmagic_help_re = re.compile('%%\w+\?')
371 line = ''
366 line = ''
372 while True:
367 while True:
373 line = (yield line)
368 line = (yield line)
374 # consume leading empty lines
369 # consume leading empty lines
375 while not line:
370 while not line:
376 line = (yield line)
371 line = (yield line)
377
372
378 if not line.startswith(ESC_MAGIC2):
373 if not line.startswith(ESC_MAGIC2):
379 # This isn't a cell magic, idle waiting for reset then start over
374 # This isn't a cell magic, idle waiting for reset then start over
380 while line is not None:
375 while line is not None:
381 line = (yield line)
376 line = (yield line)
382 continue
377 continue
383
378
384 if cellmagic_help_re.match(line):
379 if cellmagic_help_re.match(line):
385 # This case will be handled by help_end
380 # This case will be handled by help_end
386 continue
381 continue
387
382
388 first = line
383 first = line
389 body = []
384 body = []
390 line = (yield None)
385 line = (yield None)
391 while (line is not None) and \
386 while (line is not None) and \
392 ((line.strip() != '') or not end_on_blank_line):
387 ((line.strip() != '') or not end_on_blank_line):
393 body.append(line)
388 body.append(line)
394 line = (yield None)
389 line = (yield None)
395
390
396 # Output
391 # Output
397 magic_name, _, first = first.partition(' ')
392 magic_name, _, first = first.partition(' ')
398 magic_name = magic_name.lstrip(ESC_MAGIC2)
393 magic_name = magic_name.lstrip(ESC_MAGIC2)
399 line = tpl % (magic_name, first, u'\n'.join(body))
394 line = tpl % (magic_name, first, u'\n'.join(body))
400
395
401
396
402 def _strip_prompts(prompt_re, initial_re=None, turnoff_re=None):
397 def _strip_prompts(prompt_re, initial_re=None, turnoff_re=None):
403 """Remove matching input prompts from a block of input.
398 """Remove matching input prompts from a block of input.
404
399
405 Parameters
400 Parameters
406 ----------
401 ----------
407 prompt_re : regular expression
402 prompt_re : regular expression
408 A regular expression matching any input prompt (including continuation)
403 A regular expression matching any input prompt (including continuation)
409 initial_re : regular expression, optional
404 initial_re : regular expression, optional
410 A regular expression matching only the initial prompt, but not continuation.
405 A regular expression matching only the initial prompt, but not continuation.
411 If no initial expression is given, prompt_re will be used everywhere.
406 If no initial expression is given, prompt_re will be used everywhere.
412 Used mainly for plain Python prompts, where the continuation prompt
407 Used mainly for plain Python prompts, where the continuation prompt
413 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
408 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
414
409
415 If initial_re and prompt_re differ,
410 If initial_re and prompt_re differ,
416 only initial_re will be tested against the first line.
411 only initial_re will be tested against the first line.
417 If any prompt is found on the first two lines,
412 If any prompt is found on the first two lines,
418 prompts will be stripped from the rest of the block.
413 prompts will be stripped from the rest of the block.
419 """
414 """
420 if initial_re is None:
415 if initial_re is None:
421 initial_re = prompt_re
416 initial_re = prompt_re
422 line = ''
417 line = ''
423 while True:
418 while True:
424 line = (yield line)
419 line = (yield line)
425
420
426 # First line of cell
421 # First line of cell
427 if line is None:
422 if line is None:
428 continue
423 continue
429 out, n1 = initial_re.subn('', line, count=1)
424 out, n1 = initial_re.subn('', line, count=1)
430 if turnoff_re and not n1:
425 if turnoff_re and not n1:
431 if turnoff_re.match(line):
426 if turnoff_re.match(line):
432 # We're in e.g. a cell magic; disable this transformer for
427 # We're in e.g. a cell magic; disable this transformer for
433 # the rest of the cell.
428 # the rest of the cell.
434 while line is not None:
429 while line is not None:
435 line = (yield line)
430 line = (yield line)
436 continue
431 continue
437
432
438 line = (yield out)
433 line = (yield out)
439
434
440 if line is None:
435 if line is None:
441 continue
436 continue
442 # check for any prompt on the second line of the cell,
437 # check for any prompt on the second line of the cell,
443 # because people often copy from just after the first prompt,
438 # because people often copy from just after the first prompt,
444 # so we might not see it in the first line.
439 # so we might not see it in the first line.
445 out, n2 = prompt_re.subn('', line, count=1)
440 out, n2 = prompt_re.subn('', line, count=1)
446 line = (yield out)
441 line = (yield out)
447
442
448 if n1 or n2:
443 if n1 or n2:
449 # Found a prompt in the first two lines - check for it in
444 # Found a prompt in the first two lines - check for it in
450 # the rest of the cell as well.
445 # the rest of the cell as well.
451 while line is not None:
446 while line is not None:
452 line = (yield prompt_re.sub('', line, count=1))
447 line = (yield prompt_re.sub('', line, count=1))
453
448
454 else:
449 else:
455 # Prompts not in input - wait for reset
450 # Prompts not in input - wait for reset
456 while line is not None:
451 while line is not None:
457 line = (yield line)
452 line = (yield line)
458
453
459 @CoroutineInputTransformer.wrap
454 @CoroutineInputTransformer.wrap
460 def classic_prompt():
455 def classic_prompt():
461 """Strip the >>>/... prompts of the Python interactive shell."""
456 """Strip the >>>/... prompts of the Python interactive shell."""
462 # FIXME: non-capturing version (?:...) usable?
457 # FIXME: non-capturing version (?:...) usable?
463 prompt_re = re.compile(r'^(>>>|\.\.\.)( |$)')
458 prompt_re = re.compile(r'^(>>>|\.\.\.)( |$)')
464 initial_re = re.compile(r'^>>>( |$)')
459 initial_re = re.compile(r'^>>>( |$)')
465 # Any %magic/!system is IPython syntax, so we needn't look for >>> prompts
460 # Any %magic/!system is IPython syntax, so we needn't look for >>> prompts
466 turnoff_re = re.compile(r'^[%!]')
461 turnoff_re = re.compile(r'^[%!]')
467 return _strip_prompts(prompt_re, initial_re, turnoff_re)
462 return _strip_prompts(prompt_re, initial_re, turnoff_re)
468
463
469 @CoroutineInputTransformer.wrap
464 @CoroutineInputTransformer.wrap
470 def ipy_prompt():
465 def ipy_prompt():
471 """Strip IPython's In [1]:/...: prompts."""
466 """Strip IPython's In [1]:/...: prompts."""
472 # FIXME: non-capturing version (?:...) usable?
467 # FIXME: non-capturing version (?:...) usable?
473 prompt_re = re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)')
468 prompt_re = re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)')
474 # Disable prompt stripping inside cell magics
469 # Disable prompt stripping inside cell magics
475 turnoff_re = re.compile(r'^%%')
470 turnoff_re = re.compile(r'^%%')
476 return _strip_prompts(prompt_re, turnoff_re=turnoff_re)
471 return _strip_prompts(prompt_re, turnoff_re=turnoff_re)
477
472
478
473
479 @CoroutineInputTransformer.wrap
474 @CoroutineInputTransformer.wrap
480 def leading_indent():
475 def leading_indent():
481 """Remove leading indentation.
476 """Remove leading indentation.
482
477
483 If the first line starts with a spaces or tabs, the same whitespace will be
478 If the first line starts with a spaces or tabs, the same whitespace will be
484 removed from each following line until it is reset.
479 removed from each following line until it is reset.
485 """
480 """
486 space_re = re.compile(r'^[ \t]+')
481 space_re = re.compile(r'^[ \t]+')
487 line = ''
482 line = ''
488 while True:
483 while True:
489 line = (yield line)
484 line = (yield line)
490
485
491 if line is None:
486 if line is None:
492 continue
487 continue
493
488
494 m = space_re.match(line)
489 m = space_re.match(line)
495 if m:
490 if m:
496 space = m.group(0)
491 space = m.group(0)
497 while line is not None:
492 while line is not None:
498 if line.startswith(space):
493 if line.startswith(space):
499 line = line[len(space):]
494 line = line[len(space):]
500 line = (yield line)
495 line = (yield line)
501 else:
496 else:
502 # No leading spaces - wait for reset
497 # No leading spaces - wait for reset
503 while line is not None:
498 while line is not None:
504 line = (yield line)
499 line = (yield line)
505
500
506
501
507 _assign_pat = \
502 _assign_pat = \
508 r'''(?P<lhs>(\s*)
503 r'''(?P<lhs>(\s*)
509 ([\w\.]+) # Initial identifier
504 ([\w\.]+) # Initial identifier
510 (\s*,\s*
505 (\s*,\s*
511 \*?[\w\.]+)* # Further identifiers for unpacking
506 \*?[\w\.]+)* # Further identifiers for unpacking
512 \s*?,? # Trailing comma
507 \s*?,? # Trailing comma
513 )
508 )
514 \s*=\s*
509 \s*=\s*
515 '''
510 '''
516
511
517 assign_system_re = re.compile(r'{}!\s*(?P<cmd>.*)'.format(_assign_pat), re.VERBOSE)
512 assign_system_re = re.compile(r'{}!\s*(?P<cmd>.*)'.format(_assign_pat), re.VERBOSE)
518 assign_system_template = '%s = get_ipython().getoutput(%r)'
513 assign_system_template = '%s = get_ipython().getoutput(%r)'
519 @StatelessInputTransformer.wrap
514 @StatelessInputTransformer.wrap
520 def assign_from_system(line):
515 def assign_from_system(line):
521 """Transform assignment from system commands (e.g. files = !ls)"""
516 """Transform assignment from system commands (e.g. files = !ls)"""
522 m = assign_system_re.match(line)
517 m = assign_system_re.match(line)
523 if m is None:
518 if m is None:
524 return line
519 return line
525
520
526 return assign_system_template % m.group('lhs', 'cmd')
521 return assign_system_template % m.group('lhs', 'cmd')
527
522
528 assign_magic_re = re.compile(r'{}%\s*(?P<cmd>.*)'.format(_assign_pat), re.VERBOSE)
523 assign_magic_re = re.compile(r'{}%\s*(?P<cmd>.*)'.format(_assign_pat), re.VERBOSE)
529 assign_magic_template = '%s = get_ipython().magic(%r)'
524 assign_magic_template = '%s = get_ipython().magic(%r)'
530 @StatelessInputTransformer.wrap
525 @StatelessInputTransformer.wrap
531 def assign_from_magic(line):
526 def assign_from_magic(line):
532 """Transform assignment from magic commands (e.g. a = %who_ls)"""
527 """Transform assignment from magic commands (e.g. a = %who_ls)"""
533 m = assign_magic_re.match(line)
528 m = assign_magic_re.match(line)
534 if m is None:
529 if m is None:
535 return line
530 return line
536
531
537 return assign_magic_template % m.group('lhs', 'cmd')
532 return assign_magic_template % m.group('lhs', 'cmd')
@@ -1,1380 +1,1374 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Implementation of execution-related magic functions."""
2 """Implementation of execution-related magic functions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 import ast
8 import ast
9 import bdb
9 import bdb
10 import gc
10 import gc
11 import itertools
11 import itertools
12 import os
12 import os
13 import sys
13 import sys
14 import time
14 import time
15 import timeit
15 import timeit
16 import math
16 import math
17 from pdb import Restart
17 from pdb import Restart
18
18
19 # cProfile was added in Python2.5
19 # cProfile was added in Python2.5
20 try:
20 try:
21 import cProfile as profile
21 import cProfile as profile
22 import pstats
22 import pstats
23 except ImportError:
23 except ImportError:
24 # profile isn't bundled by default in Debian for license reasons
24 # profile isn't bundled by default in Debian for license reasons
25 try:
25 try:
26 import profile, pstats
26 import profile, pstats
27 except ImportError:
27 except ImportError:
28 profile = pstats = None
28 profile = pstats = None
29
29
30 from IPython.core import oinspect
30 from IPython.core import oinspect
31 from IPython.core import magic_arguments
31 from IPython.core import magic_arguments
32 from IPython.core import page
32 from IPython.core import page
33 from IPython.core.error import UsageError
33 from IPython.core.error import UsageError
34 from IPython.core.macro import Macro
34 from IPython.core.macro import Macro
35 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
35 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
36 line_cell_magic, on_off, needs_local_scope)
36 line_cell_magic, on_off, needs_local_scope)
37 from IPython.testing.skipdoctest import skip_doctest
37 from IPython.testing.skipdoctest import skip_doctest
38 from IPython.utils import py3compat
38 from IPython.utils import py3compat
39 from IPython.utils.py3compat import builtin_mod, PY3
39 from IPython.utils.py3compat import builtin_mod
40 from IPython.utils.contexts import preserve_keys
40 from IPython.utils.contexts import preserve_keys
41 from IPython.utils.capture import capture_output
41 from IPython.utils.capture import capture_output
42 from IPython.utils.ipstruct import Struct
42 from IPython.utils.ipstruct import Struct
43 from IPython.utils.module_paths import find_mod
43 from IPython.utils.module_paths import find_mod
44 from IPython.utils.path import get_py_filename, shellglob
44 from IPython.utils.path import get_py_filename, shellglob
45 from IPython.utils.timing import clock, clock2
45 from IPython.utils.timing import clock, clock2
46 from warnings import warn
46 from warnings import warn
47 from logging import error
47 from logging import error
48
49 if PY3:
50 from io import StringIO
48 from io import StringIO
51 else:
49
52 from StringIO import StringIO
53
50
54 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
55 # Magic implementation classes
52 # Magic implementation classes
56 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
57
54
58
55
59 class TimeitResult(object):
56 class TimeitResult(object):
60 """
57 """
61 Object returned by the timeit magic with info about the run.
58 Object returned by the timeit magic with info about the run.
62
59
63 Contains the following attributes :
60 Contains the following attributes :
64
61
65 loops: (int) number of loops done per measurement
62 loops: (int) number of loops done per measurement
66 repeat: (int) number of times the measurement has been repeated
63 repeat: (int) number of times the measurement has been repeated
67 best: (float) best execution time / number
64 best: (float) best execution time / number
68 all_runs: (list of float) execution time of each run (in s)
65 all_runs: (list of float) execution time of each run (in s)
69 compile_time: (float) time of statement compilation (s)
66 compile_time: (float) time of statement compilation (s)
70
67
71 """
68 """
72 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
69 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
73 self.loops = loops
70 self.loops = loops
74 self.repeat = repeat
71 self.repeat = repeat
75 self.best = best
72 self.best = best
76 self.worst = worst
73 self.worst = worst
77 self.all_runs = all_runs
74 self.all_runs = all_runs
78 self.compile_time = compile_time
75 self.compile_time = compile_time
79 self._precision = precision
76 self._precision = precision
80 self.timings = [ dt / self.loops for dt in all_runs]
77 self.timings = [ dt / self.loops for dt in all_runs]
81
78
82 @property
79 @property
83 def average(self):
80 def average(self):
84 return math.fsum(self.timings) / len(self.timings)
81 return math.fsum(self.timings) / len(self.timings)
85
82
86 @property
83 @property
87 def stdev(self):
84 def stdev(self):
88 mean = self.average
85 mean = self.average
89 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
86 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
90
87
91 def __str__(self):
88 def __str__(self):
92 return (u"%s loop%s, average of %d: %s +- %s per loop (using standard deviation)"
89 return (u"%s loop%s, average of %d: %s +- %s per loop (using standard deviation)"
93 % (self.loops,"" if self.loops == 1 else "s", self.repeat,
90 % (self.loops,"" if self.loops == 1 else "s", self.repeat,
94 _format_time(self.average, self._precision),
91 _format_time(self.average, self._precision),
95 _format_time(self.stdev, self._precision)))
92 _format_time(self.stdev, self._precision)))
96
93
97 def _repr_pretty_(self, p , cycle):
94 def _repr_pretty_(self, p , cycle):
98 unic = self.__str__()
95 unic = self.__str__()
99 p.text(u'<TimeitResult : '+unic+u'>')
96 p.text(u'<TimeitResult : '+unic+u'>')
100
97
101
98
102
99
103 class TimeitTemplateFiller(ast.NodeTransformer):
100 class TimeitTemplateFiller(ast.NodeTransformer):
104 """Fill in the AST template for timing execution.
101 """Fill in the AST template for timing execution.
105
102
106 This is quite closely tied to the template definition, which is in
103 This is quite closely tied to the template definition, which is in
107 :meth:`ExecutionMagics.timeit`.
104 :meth:`ExecutionMagics.timeit`.
108 """
105 """
109 def __init__(self, ast_setup, ast_stmt):
106 def __init__(self, ast_setup, ast_stmt):
110 self.ast_setup = ast_setup
107 self.ast_setup = ast_setup
111 self.ast_stmt = ast_stmt
108 self.ast_stmt = ast_stmt
112
109
113 def visit_FunctionDef(self, node):
110 def visit_FunctionDef(self, node):
114 "Fill in the setup statement"
111 "Fill in the setup statement"
115 self.generic_visit(node)
112 self.generic_visit(node)
116 if node.name == "inner":
113 if node.name == "inner":
117 node.body[:1] = self.ast_setup.body
114 node.body[:1] = self.ast_setup.body
118
115
119 return node
116 return node
120
117
121 def visit_For(self, node):
118 def visit_For(self, node):
122 "Fill in the statement to be timed"
119 "Fill in the statement to be timed"
123 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
120 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
124 node.body = self.ast_stmt.body
121 node.body = self.ast_stmt.body
125 return node
122 return node
126
123
127
124
128 class Timer(timeit.Timer):
125 class Timer(timeit.Timer):
129 """Timer class that explicitly uses self.inner
126 """Timer class that explicitly uses self.inner
130
127
131 which is an undocumented implementation detail of CPython,
128 which is an undocumented implementation detail of CPython,
132 not shared by PyPy.
129 not shared by PyPy.
133 """
130 """
134 # Timer.timeit copied from CPython 3.4.2
131 # Timer.timeit copied from CPython 3.4.2
135 def timeit(self, number=timeit.default_number):
132 def timeit(self, number=timeit.default_number):
136 """Time 'number' executions of the main statement.
133 """Time 'number' executions of the main statement.
137
134
138 To be precise, this executes the setup statement once, and
135 To be precise, this executes the setup statement once, and
139 then returns the time it takes to execute the main statement
136 then returns the time it takes to execute the main statement
140 a number of times, as a float measured in seconds. The
137 a number of times, as a float measured in seconds. The
141 argument is the number of times through the loop, defaulting
138 argument is the number of times through the loop, defaulting
142 to one million. The main statement, the setup statement and
139 to one million. The main statement, the setup statement and
143 the timer function to be used are passed to the constructor.
140 the timer function to be used are passed to the constructor.
144 """
141 """
145 it = itertools.repeat(None, number)
142 it = itertools.repeat(None, number)
146 gcold = gc.isenabled()
143 gcold = gc.isenabled()
147 gc.disable()
144 gc.disable()
148 try:
145 try:
149 timing = self.inner(it, self.timer)
146 timing = self.inner(it, self.timer)
150 finally:
147 finally:
151 if gcold:
148 if gcold:
152 gc.enable()
149 gc.enable()
153 return timing
150 return timing
154
151
155
152
156 @magics_class
153 @magics_class
157 class ExecutionMagics(Magics):
154 class ExecutionMagics(Magics):
158 """Magics related to code execution, debugging, profiling, etc.
155 """Magics related to code execution, debugging, profiling, etc.
159
156
160 """
157 """
161
158
162 def __init__(self, shell):
159 def __init__(self, shell):
163 super(ExecutionMagics, self).__init__(shell)
160 super(ExecutionMagics, self).__init__(shell)
164 if profile is None:
161 if profile is None:
165 self.prun = self.profile_missing_notice
162 self.prun = self.profile_missing_notice
166 # Default execution function used to actually run user code.
163 # Default execution function used to actually run user code.
167 self.default_runner = None
164 self.default_runner = None
168
165
169 def profile_missing_notice(self, *args, **kwargs):
166 def profile_missing_notice(self, *args, **kwargs):
170 error("""\
167 error("""\
171 The profile module could not be found. It has been removed from the standard
168 The profile module could not be found. It has been removed from the standard
172 python packages because of its non-free license. To use profiling, install the
169 python packages because of its non-free license. To use profiling, install the
173 python-profiler package from non-free.""")
170 python-profiler package from non-free.""")
174
171
175 @skip_doctest
172 @skip_doctest
176 @line_cell_magic
173 @line_cell_magic
177 def prun(self, parameter_s='', cell=None):
174 def prun(self, parameter_s='', cell=None):
178
175
179 """Run a statement through the python code profiler.
176 """Run a statement through the python code profiler.
180
177
181 Usage, in line mode:
178 Usage, in line mode:
182 %prun [options] statement
179 %prun [options] statement
183
180
184 Usage, in cell mode:
181 Usage, in cell mode:
185 %%prun [options] [statement]
182 %%prun [options] [statement]
186 code...
183 code...
187 code...
184 code...
188
185
189 In cell mode, the additional code lines are appended to the (possibly
186 In cell mode, the additional code lines are appended to the (possibly
190 empty) statement in the first line. Cell mode allows you to easily
187 empty) statement in the first line. Cell mode allows you to easily
191 profile multiline blocks without having to put them in a separate
188 profile multiline blocks without having to put them in a separate
192 function.
189 function.
193
190
194 The given statement (which doesn't require quote marks) is run via the
191 The given statement (which doesn't require quote marks) is run via the
195 python profiler in a manner similar to the profile.run() function.
192 python profiler in a manner similar to the profile.run() function.
196 Namespaces are internally managed to work correctly; profile.run
193 Namespaces are internally managed to work correctly; profile.run
197 cannot be used in IPython because it makes certain assumptions about
194 cannot be used in IPython because it makes certain assumptions about
198 namespaces which do not hold under IPython.
195 namespaces which do not hold under IPython.
199
196
200 Options:
197 Options:
201
198
202 -l <limit>
199 -l <limit>
203 you can place restrictions on what or how much of the
200 you can place restrictions on what or how much of the
204 profile gets printed. The limit value can be:
201 profile gets printed. The limit value can be:
205
202
206 * A string: only information for function names containing this string
203 * A string: only information for function names containing this string
207 is printed.
204 is printed.
208
205
209 * An integer: only these many lines are printed.
206 * An integer: only these many lines are printed.
210
207
211 * A float (between 0 and 1): this fraction of the report is printed
208 * A float (between 0 and 1): this fraction of the report is printed
212 (for example, use a limit of 0.4 to see the topmost 40% only).
209 (for example, use a limit of 0.4 to see the topmost 40% only).
213
210
214 You can combine several limits with repeated use of the option. For
211 You can combine several limits with repeated use of the option. For
215 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
212 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
216 information about class constructors.
213 information about class constructors.
217
214
218 -r
215 -r
219 return the pstats.Stats object generated by the profiling. This
216 return the pstats.Stats object generated by the profiling. This
220 object has all the information about the profile in it, and you can
217 object has all the information about the profile in it, and you can
221 later use it for further analysis or in other functions.
218 later use it for further analysis or in other functions.
222
219
223 -s <key>
220 -s <key>
224 sort profile by given key. You can provide more than one key
221 sort profile by given key. You can provide more than one key
225 by using the option several times: '-s key1 -s key2 -s key3...'. The
222 by using the option several times: '-s key1 -s key2 -s key3...'. The
226 default sorting key is 'time'.
223 default sorting key is 'time'.
227
224
228 The following is copied verbatim from the profile documentation
225 The following is copied verbatim from the profile documentation
229 referenced below:
226 referenced below:
230
227
231 When more than one key is provided, additional keys are used as
228 When more than one key is provided, additional keys are used as
232 secondary criteria when the there is equality in all keys selected
229 secondary criteria when the there is equality in all keys selected
233 before them.
230 before them.
234
231
235 Abbreviations can be used for any key names, as long as the
232 Abbreviations can be used for any key names, as long as the
236 abbreviation is unambiguous. The following are the keys currently
233 abbreviation is unambiguous. The following are the keys currently
237 defined:
234 defined:
238
235
239 ============ =====================
236 ============ =====================
240 Valid Arg Meaning
237 Valid Arg Meaning
241 ============ =====================
238 ============ =====================
242 "calls" call count
239 "calls" call count
243 "cumulative" cumulative time
240 "cumulative" cumulative time
244 "file" file name
241 "file" file name
245 "module" file name
242 "module" file name
246 "pcalls" primitive call count
243 "pcalls" primitive call count
247 "line" line number
244 "line" line number
248 "name" function name
245 "name" function name
249 "nfl" name/file/line
246 "nfl" name/file/line
250 "stdname" standard name
247 "stdname" standard name
251 "time" internal time
248 "time" internal time
252 ============ =====================
249 ============ =====================
253
250
254 Note that all sorts on statistics are in descending order (placing
251 Note that all sorts on statistics are in descending order (placing
255 most time consuming items first), where as name, file, and line number
252 most time consuming items first), where as name, file, and line number
256 searches are in ascending order (i.e., alphabetical). The subtle
253 searches are in ascending order (i.e., alphabetical). The subtle
257 distinction between "nfl" and "stdname" is that the standard name is a
254 distinction between "nfl" and "stdname" is that the standard name is a
258 sort of the name as printed, which means that the embedded line
255 sort of the name as printed, which means that the embedded line
259 numbers get compared in an odd way. For example, lines 3, 20, and 40
256 numbers get compared in an odd way. For example, lines 3, 20, and 40
260 would (if the file names were the same) appear in the string order
257 would (if the file names were the same) appear in the string order
261 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
258 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
262 line numbers. In fact, sort_stats("nfl") is the same as
259 line numbers. In fact, sort_stats("nfl") is the same as
263 sort_stats("name", "file", "line").
260 sort_stats("name", "file", "line").
264
261
265 -T <filename>
262 -T <filename>
266 save profile results as shown on screen to a text
263 save profile results as shown on screen to a text
267 file. The profile is still shown on screen.
264 file. The profile is still shown on screen.
268
265
269 -D <filename>
266 -D <filename>
270 save (via dump_stats) profile statistics to given
267 save (via dump_stats) profile statistics to given
271 filename. This data is in a format understood by the pstats module, and
268 filename. This data is in a format understood by the pstats module, and
272 is generated by a call to the dump_stats() method of profile
269 is generated by a call to the dump_stats() method of profile
273 objects. The profile is still shown on screen.
270 objects. The profile is still shown on screen.
274
271
275 -q
272 -q
276 suppress output to the pager. Best used with -T and/or -D above.
273 suppress output to the pager. Best used with -T and/or -D above.
277
274
278 If you want to run complete programs under the profiler's control, use
275 If you want to run complete programs under the profiler's control, use
279 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
276 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
280 contains profiler specific options as described here.
277 contains profiler specific options as described here.
281
278
282 You can read the complete documentation for the profile module with::
279 You can read the complete documentation for the profile module with::
283
280
284 In [1]: import profile; profile.help()
281 In [1]: import profile; profile.help()
285 """
282 """
286 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
283 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
287 list_all=True, posix=False)
284 list_all=True, posix=False)
288 if cell is not None:
285 if cell is not None:
289 arg_str += '\n' + cell
286 arg_str += '\n' + cell
290 arg_str = self.shell.input_splitter.transform_cell(arg_str)
287 arg_str = self.shell.input_splitter.transform_cell(arg_str)
291 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
288 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
292
289
293 def _run_with_profiler(self, code, opts, namespace):
290 def _run_with_profiler(self, code, opts, namespace):
294 """
291 """
295 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
292 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
296
293
297 Parameters
294 Parameters
298 ----------
295 ----------
299 code : str
296 code : str
300 Code to be executed.
297 Code to be executed.
301 opts : Struct
298 opts : Struct
302 Options parsed by `self.parse_options`.
299 Options parsed by `self.parse_options`.
303 namespace : dict
300 namespace : dict
304 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
301 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
305
302
306 """
303 """
307
304
308 # Fill default values for unspecified options:
305 # Fill default values for unspecified options:
309 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
306 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
310
307
311 prof = profile.Profile()
308 prof = profile.Profile()
312 try:
309 try:
313 prof = prof.runctx(code, namespace, namespace)
310 prof = prof.runctx(code, namespace, namespace)
314 sys_exit = ''
311 sys_exit = ''
315 except SystemExit:
312 except SystemExit:
316 sys_exit = """*** SystemExit exception caught in code being profiled."""
313 sys_exit = """*** SystemExit exception caught in code being profiled."""
317
314
318 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
315 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
319
316
320 lims = opts.l
317 lims = opts.l
321 if lims:
318 if lims:
322 lims = [] # rebuild lims with ints/floats/strings
319 lims = [] # rebuild lims with ints/floats/strings
323 for lim in opts.l:
320 for lim in opts.l:
324 try:
321 try:
325 lims.append(int(lim))
322 lims.append(int(lim))
326 except ValueError:
323 except ValueError:
327 try:
324 try:
328 lims.append(float(lim))
325 lims.append(float(lim))
329 except ValueError:
326 except ValueError:
330 lims.append(lim)
327 lims.append(lim)
331
328
332 # Trap output.
329 # Trap output.
333 stdout_trap = StringIO()
330 stdout_trap = StringIO()
334 stats_stream = stats.stream
331 stats_stream = stats.stream
335 try:
332 try:
336 stats.stream = stdout_trap
333 stats.stream = stdout_trap
337 stats.print_stats(*lims)
334 stats.print_stats(*lims)
338 finally:
335 finally:
339 stats.stream = stats_stream
336 stats.stream = stats_stream
340
337
341 output = stdout_trap.getvalue()
338 output = stdout_trap.getvalue()
342 output = output.rstrip()
339 output = output.rstrip()
343
340
344 if 'q' not in opts:
341 if 'q' not in opts:
345 page.page(output)
342 page.page(output)
346 print(sys_exit, end=' ')
343 print(sys_exit, end=' ')
347
344
348 dump_file = opts.D[0]
345 dump_file = opts.D[0]
349 text_file = opts.T[0]
346 text_file = opts.T[0]
350 if dump_file:
347 if dump_file:
351 prof.dump_stats(dump_file)
348 prof.dump_stats(dump_file)
352 print('\n*** Profile stats marshalled to file',\
349 print('\n*** Profile stats marshalled to file',\
353 repr(dump_file)+'.',sys_exit)
350 repr(dump_file)+'.',sys_exit)
354 if text_file:
351 if text_file:
355 pfile = open(text_file,'w')
352 pfile = open(text_file,'w')
356 pfile.write(output)
353 pfile.write(output)
357 pfile.close()
354 pfile.close()
358 print('\n*** Profile printout saved to text file',\
355 print('\n*** Profile printout saved to text file',\
359 repr(text_file)+'.',sys_exit)
356 repr(text_file)+'.',sys_exit)
360
357
361 if 'r' in opts:
358 if 'r' in opts:
362 return stats
359 return stats
363 else:
360 else:
364 return None
361 return None
365
362
366 @line_magic
363 @line_magic
367 def pdb(self, parameter_s=''):
364 def pdb(self, parameter_s=''):
368 """Control the automatic calling of the pdb interactive debugger.
365 """Control the automatic calling of the pdb interactive debugger.
369
366
370 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
367 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
371 argument it works as a toggle.
368 argument it works as a toggle.
372
369
373 When an exception is triggered, IPython can optionally call the
370 When an exception is triggered, IPython can optionally call the
374 interactive pdb debugger after the traceback printout. %pdb toggles
371 interactive pdb debugger after the traceback printout. %pdb toggles
375 this feature on and off.
372 this feature on and off.
376
373
377 The initial state of this feature is set in your configuration
374 The initial state of this feature is set in your configuration
378 file (the option is ``InteractiveShell.pdb``).
375 file (the option is ``InteractiveShell.pdb``).
379
376
380 If you want to just activate the debugger AFTER an exception has fired,
377 If you want to just activate the debugger AFTER an exception has fired,
381 without having to type '%pdb on' and rerunning your code, you can use
378 without having to type '%pdb on' and rerunning your code, you can use
382 the %debug magic."""
379 the %debug magic."""
383
380
384 par = parameter_s.strip().lower()
381 par = parameter_s.strip().lower()
385
382
386 if par:
383 if par:
387 try:
384 try:
388 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
385 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
389 except KeyError:
386 except KeyError:
390 print ('Incorrect argument. Use on/1, off/0, '
387 print ('Incorrect argument. Use on/1, off/0, '
391 'or nothing for a toggle.')
388 'or nothing for a toggle.')
392 return
389 return
393 else:
390 else:
394 # toggle
391 # toggle
395 new_pdb = not self.shell.call_pdb
392 new_pdb = not self.shell.call_pdb
396
393
397 # set on the shell
394 # set on the shell
398 self.shell.call_pdb = new_pdb
395 self.shell.call_pdb = new_pdb
399 print('Automatic pdb calling has been turned',on_off(new_pdb))
396 print('Automatic pdb calling has been turned',on_off(new_pdb))
400
397
401 @skip_doctest
398 @skip_doctest
402 @magic_arguments.magic_arguments()
399 @magic_arguments.magic_arguments()
403 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
400 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
404 help="""
401 help="""
405 Set break point at LINE in FILE.
402 Set break point at LINE in FILE.
406 """
403 """
407 )
404 )
408 @magic_arguments.argument('statement', nargs='*',
405 @magic_arguments.argument('statement', nargs='*',
409 help="""
406 help="""
410 Code to run in debugger.
407 Code to run in debugger.
411 You can omit this in cell magic mode.
408 You can omit this in cell magic mode.
412 """
409 """
413 )
410 )
414 @line_cell_magic
411 @line_cell_magic
415 def debug(self, line='', cell=None):
412 def debug(self, line='', cell=None):
416 """Activate the interactive debugger.
413 """Activate the interactive debugger.
417
414
418 This magic command support two ways of activating debugger.
415 This magic command support two ways of activating debugger.
419 One is to activate debugger before executing code. This way, you
416 One is to activate debugger before executing code. This way, you
420 can set a break point, to step through the code from the point.
417 can set a break point, to step through the code from the point.
421 You can use this mode by giving statements to execute and optionally
418 You can use this mode by giving statements to execute and optionally
422 a breakpoint.
419 a breakpoint.
423
420
424 The other one is to activate debugger in post-mortem mode. You can
421 The other one is to activate debugger in post-mortem mode. You can
425 activate this mode simply running %debug without any argument.
422 activate this mode simply running %debug without any argument.
426 If an exception has just occurred, this lets you inspect its stack
423 If an exception has just occurred, this lets you inspect its stack
427 frames interactively. Note that this will always work only on the last
424 frames interactively. Note that this will always work only on the last
428 traceback that occurred, so you must call this quickly after an
425 traceback that occurred, so you must call this quickly after an
429 exception that you wish to inspect has fired, because if another one
426 exception that you wish to inspect has fired, because if another one
430 occurs, it clobbers the previous one.
427 occurs, it clobbers the previous one.
431
428
432 If you want IPython to automatically do this on every exception, see
429 If you want IPython to automatically do this on every exception, see
433 the %pdb magic for more details.
430 the %pdb magic for more details.
434 """
431 """
435 args = magic_arguments.parse_argstring(self.debug, line)
432 args = magic_arguments.parse_argstring(self.debug, line)
436
433
437 if not (args.breakpoint or args.statement or cell):
434 if not (args.breakpoint or args.statement or cell):
438 self._debug_post_mortem()
435 self._debug_post_mortem()
439 else:
436 else:
440 code = "\n".join(args.statement)
437 code = "\n".join(args.statement)
441 if cell:
438 if cell:
442 code += "\n" + cell
439 code += "\n" + cell
443 self._debug_exec(code, args.breakpoint)
440 self._debug_exec(code, args.breakpoint)
444
441
445 def _debug_post_mortem(self):
442 def _debug_post_mortem(self):
446 self.shell.debugger(force=True)
443 self.shell.debugger(force=True)
447
444
448 def _debug_exec(self, code, breakpoint):
445 def _debug_exec(self, code, breakpoint):
449 if breakpoint:
446 if breakpoint:
450 (filename, bp_line) = breakpoint.rsplit(':', 1)
447 (filename, bp_line) = breakpoint.rsplit(':', 1)
451 bp_line = int(bp_line)
448 bp_line = int(bp_line)
452 else:
449 else:
453 (filename, bp_line) = (None, None)
450 (filename, bp_line) = (None, None)
454 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
451 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
455
452
456 @line_magic
453 @line_magic
457 def tb(self, s):
454 def tb(self, s):
458 """Print the last traceback with the currently active exception mode.
455 """Print the last traceback with the currently active exception mode.
459
456
460 See %xmode for changing exception reporting modes."""
457 See %xmode for changing exception reporting modes."""
461 self.shell.showtraceback()
458 self.shell.showtraceback()
462
459
463 @skip_doctest
460 @skip_doctest
464 @line_magic
461 @line_magic
465 def run(self, parameter_s='', runner=None,
462 def run(self, parameter_s='', runner=None,
466 file_finder=get_py_filename):
463 file_finder=get_py_filename):
467 """Run the named file inside IPython as a program.
464 """Run the named file inside IPython as a program.
468
465
469 Usage::
466 Usage::
470
467
471 %run [-n -i -e -G]
468 %run [-n -i -e -G]
472 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
469 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
473 ( -m mod | file ) [args]
470 ( -m mod | file ) [args]
474
471
475 Parameters after the filename are passed as command-line arguments to
472 Parameters after the filename are passed as command-line arguments to
476 the program (put in sys.argv). Then, control returns to IPython's
473 the program (put in sys.argv). Then, control returns to IPython's
477 prompt.
474 prompt.
478
475
479 This is similar to running at a system prompt ``python file args``,
476 This is similar to running at a system prompt ``python file args``,
480 but with the advantage of giving you IPython's tracebacks, and of
477 but with the advantage of giving you IPython's tracebacks, and of
481 loading all variables into your interactive namespace for further use
478 loading all variables into your interactive namespace for further use
482 (unless -p is used, see below).
479 (unless -p is used, see below).
483
480
484 The file is executed in a namespace initially consisting only of
481 The file is executed in a namespace initially consisting only of
485 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
482 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
486 sees its environment as if it were being run as a stand-alone program
483 sees its environment as if it were being run as a stand-alone program
487 (except for sharing global objects such as previously imported
484 (except for sharing global objects such as previously imported
488 modules). But after execution, the IPython interactive namespace gets
485 modules). But after execution, the IPython interactive namespace gets
489 updated with all variables defined in the program (except for __name__
486 updated with all variables defined in the program (except for __name__
490 and sys.argv). This allows for very convenient loading of code for
487 and sys.argv). This allows for very convenient loading of code for
491 interactive work, while giving each program a 'clean sheet' to run in.
488 interactive work, while giving each program a 'clean sheet' to run in.
492
489
493 Arguments are expanded using shell-like glob match. Patterns
490 Arguments are expanded using shell-like glob match. Patterns
494 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
491 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
495 tilde '~' will be expanded into user's home directory. Unlike
492 tilde '~' will be expanded into user's home directory. Unlike
496 real shells, quotation does not suppress expansions. Use
493 real shells, quotation does not suppress expansions. Use
497 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
494 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
498 To completely disable these expansions, you can use -G flag.
495 To completely disable these expansions, you can use -G flag.
499
496
500 Options:
497 Options:
501
498
502 -n
499 -n
503 __name__ is NOT set to '__main__', but to the running file's name
500 __name__ is NOT set to '__main__', but to the running file's name
504 without extension (as python does under import). This allows running
501 without extension (as python does under import). This allows running
505 scripts and reloading the definitions in them without calling code
502 scripts and reloading the definitions in them without calling code
506 protected by an ``if __name__ == "__main__"`` clause.
503 protected by an ``if __name__ == "__main__"`` clause.
507
504
508 -i
505 -i
509 run the file in IPython's namespace instead of an empty one. This
506 run the file in IPython's namespace instead of an empty one. This
510 is useful if you are experimenting with code written in a text editor
507 is useful if you are experimenting with code written in a text editor
511 which depends on variables defined interactively.
508 which depends on variables defined interactively.
512
509
513 -e
510 -e
514 ignore sys.exit() calls or SystemExit exceptions in the script
511 ignore sys.exit() calls or SystemExit exceptions in the script
515 being run. This is particularly useful if IPython is being used to
512 being run. This is particularly useful if IPython is being used to
516 run unittests, which always exit with a sys.exit() call. In such
513 run unittests, which always exit with a sys.exit() call. In such
517 cases you are interested in the output of the test results, not in
514 cases you are interested in the output of the test results, not in
518 seeing a traceback of the unittest module.
515 seeing a traceback of the unittest module.
519
516
520 -t
517 -t
521 print timing information at the end of the run. IPython will give
518 print timing information at the end of the run. IPython will give
522 you an estimated CPU time consumption for your script, which under
519 you an estimated CPU time consumption for your script, which under
523 Unix uses the resource module to avoid the wraparound problems of
520 Unix uses the resource module to avoid the wraparound problems of
524 time.clock(). Under Unix, an estimate of time spent on system tasks
521 time.clock(). Under Unix, an estimate of time spent on system tasks
525 is also given (for Windows platforms this is reported as 0.0).
522 is also given (for Windows platforms this is reported as 0.0).
526
523
527 If -t is given, an additional ``-N<N>`` option can be given, where <N>
524 If -t is given, an additional ``-N<N>`` option can be given, where <N>
528 must be an integer indicating how many times you want the script to
525 must be an integer indicating how many times you want the script to
529 run. The final timing report will include total and per run results.
526 run. The final timing report will include total and per run results.
530
527
531 For example (testing the script uniq_stable.py)::
528 For example (testing the script uniq_stable.py)::
532
529
533 In [1]: run -t uniq_stable
530 In [1]: run -t uniq_stable
534
531
535 IPython CPU timings (estimated):
532 IPython CPU timings (estimated):
536 User : 0.19597 s.
533 User : 0.19597 s.
537 System: 0.0 s.
534 System: 0.0 s.
538
535
539 In [2]: run -t -N5 uniq_stable
536 In [2]: run -t -N5 uniq_stable
540
537
541 IPython CPU timings (estimated):
538 IPython CPU timings (estimated):
542 Total runs performed: 5
539 Total runs performed: 5
543 Times : Total Per run
540 Times : Total Per run
544 User : 0.910862 s, 0.1821724 s.
541 User : 0.910862 s, 0.1821724 s.
545 System: 0.0 s, 0.0 s.
542 System: 0.0 s, 0.0 s.
546
543
547 -d
544 -d
548 run your program under the control of pdb, the Python debugger.
545 run your program under the control of pdb, the Python debugger.
549 This allows you to execute your program step by step, watch variables,
546 This allows you to execute your program step by step, watch variables,
550 etc. Internally, what IPython does is similar to calling::
547 etc. Internally, what IPython does is similar to calling::
551
548
552 pdb.run('execfile("YOURFILENAME")')
549 pdb.run('execfile("YOURFILENAME")')
553
550
554 with a breakpoint set on line 1 of your file. You can change the line
551 with a breakpoint set on line 1 of your file. You can change the line
555 number for this automatic breakpoint to be <N> by using the -bN option
552 number for this automatic breakpoint to be <N> by using the -bN option
556 (where N must be an integer). For example::
553 (where N must be an integer). For example::
557
554
558 %run -d -b40 myscript
555 %run -d -b40 myscript
559
556
560 will set the first breakpoint at line 40 in myscript.py. Note that
557 will set the first breakpoint at line 40 in myscript.py. Note that
561 the first breakpoint must be set on a line which actually does
558 the first breakpoint must be set on a line which actually does
562 something (not a comment or docstring) for it to stop execution.
559 something (not a comment or docstring) for it to stop execution.
563
560
564 Or you can specify a breakpoint in a different file::
561 Or you can specify a breakpoint in a different file::
565
562
566 %run -d -b myotherfile.py:20 myscript
563 %run -d -b myotherfile.py:20 myscript
567
564
568 When the pdb debugger starts, you will see a (Pdb) prompt. You must
565 When the pdb debugger starts, you will see a (Pdb) prompt. You must
569 first enter 'c' (without quotes) to start execution up to the first
566 first enter 'c' (without quotes) to start execution up to the first
570 breakpoint.
567 breakpoint.
571
568
572 Entering 'help' gives information about the use of the debugger. You
569 Entering 'help' gives information about the use of the debugger. You
573 can easily see pdb's full documentation with "import pdb;pdb.help()"
570 can easily see pdb's full documentation with "import pdb;pdb.help()"
574 at a prompt.
571 at a prompt.
575
572
576 -p
573 -p
577 run program under the control of the Python profiler module (which
574 run program under the control of the Python profiler module (which
578 prints a detailed report of execution times, function calls, etc).
575 prints a detailed report of execution times, function calls, etc).
579
576
580 You can pass other options after -p which affect the behavior of the
577 You can pass other options after -p which affect the behavior of the
581 profiler itself. See the docs for %prun for details.
578 profiler itself. See the docs for %prun for details.
582
579
583 In this mode, the program's variables do NOT propagate back to the
580 In this mode, the program's variables do NOT propagate back to the
584 IPython interactive namespace (because they remain in the namespace
581 IPython interactive namespace (because they remain in the namespace
585 where the profiler executes them).
582 where the profiler executes them).
586
583
587 Internally this triggers a call to %prun, see its documentation for
584 Internally this triggers a call to %prun, see its documentation for
588 details on the options available specifically for profiling.
585 details on the options available specifically for profiling.
589
586
590 There is one special usage for which the text above doesn't apply:
587 There is one special usage for which the text above doesn't apply:
591 if the filename ends with .ipy[nb], the file is run as ipython script,
588 if the filename ends with .ipy[nb], the file is run as ipython script,
592 just as if the commands were written on IPython prompt.
589 just as if the commands were written on IPython prompt.
593
590
594 -m
591 -m
595 specify module name to load instead of script path. Similar to
592 specify module name to load instead of script path. Similar to
596 the -m option for the python interpreter. Use this option last if you
593 the -m option for the python interpreter. Use this option last if you
597 want to combine with other %run options. Unlike the python interpreter
594 want to combine with other %run options. Unlike the python interpreter
598 only source modules are allowed no .pyc or .pyo files.
595 only source modules are allowed no .pyc or .pyo files.
599 For example::
596 For example::
600
597
601 %run -m example
598 %run -m example
602
599
603 will run the example module.
600 will run the example module.
604
601
605 -G
602 -G
606 disable shell-like glob expansion of arguments.
603 disable shell-like glob expansion of arguments.
607
604
608 """
605 """
609
606
610 # get arguments and set sys.argv for program to be run.
607 # get arguments and set sys.argv for program to be run.
611 opts, arg_lst = self.parse_options(parameter_s,
608 opts, arg_lst = self.parse_options(parameter_s,
612 'nidtN:b:pD:l:rs:T:em:G',
609 'nidtN:b:pD:l:rs:T:em:G',
613 mode='list', list_all=1)
610 mode='list', list_all=1)
614 if "m" in opts:
611 if "m" in opts:
615 modulename = opts["m"][0]
612 modulename = opts["m"][0]
616 modpath = find_mod(modulename)
613 modpath = find_mod(modulename)
617 if modpath is None:
614 if modpath is None:
618 warn('%r is not a valid modulename on sys.path'%modulename)
615 warn('%r is not a valid modulename on sys.path'%modulename)
619 return
616 return
620 arg_lst = [modpath] + arg_lst
617 arg_lst = [modpath] + arg_lst
621 try:
618 try:
622 filename = file_finder(arg_lst[0])
619 filename = file_finder(arg_lst[0])
623 except IndexError:
620 except IndexError:
624 warn('you must provide at least a filename.')
621 warn('you must provide at least a filename.')
625 print('\n%run:\n', oinspect.getdoc(self.run))
622 print('\n%run:\n', oinspect.getdoc(self.run))
626 return
623 return
627 except IOError as e:
624 except IOError as e:
628 try:
625 try:
629 msg = str(e)
626 msg = str(e)
630 except UnicodeError:
627 except UnicodeError:
631 msg = e.message
628 msg = e.message
632 error(msg)
629 error(msg)
633 return
630 return
634
631
635 if filename.lower().endswith(('.ipy', '.ipynb')):
632 if filename.lower().endswith(('.ipy', '.ipynb')):
636 with preserve_keys(self.shell.user_ns, '__file__'):
633 with preserve_keys(self.shell.user_ns, '__file__'):
637 self.shell.user_ns['__file__'] = filename
634 self.shell.user_ns['__file__'] = filename
638 self.shell.safe_execfile_ipy(filename)
635 self.shell.safe_execfile_ipy(filename)
639 return
636 return
640
637
641 # Control the response to exit() calls made by the script being run
638 # Control the response to exit() calls made by the script being run
642 exit_ignore = 'e' in opts
639 exit_ignore = 'e' in opts
643
640
644 # Make sure that the running script gets a proper sys.argv as if it
641 # Make sure that the running script gets a proper sys.argv as if it
645 # were run from a system shell.
642 # were run from a system shell.
646 save_argv = sys.argv # save it for later restoring
643 save_argv = sys.argv # save it for later restoring
647
644
648 if 'G' in opts:
645 if 'G' in opts:
649 args = arg_lst[1:]
646 args = arg_lst[1:]
650 else:
647 else:
651 # tilde and glob expansion
648 # tilde and glob expansion
652 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
649 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
653
650
654 sys.argv = [filename] + args # put in the proper filename
651 sys.argv = [filename] + args # put in the proper filename
655 # protect sys.argv from potential unicode strings on Python 2:
656 if not py3compat.PY3:
657 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
658
652
659 if 'i' in opts:
653 if 'i' in opts:
660 # Run in user's interactive namespace
654 # Run in user's interactive namespace
661 prog_ns = self.shell.user_ns
655 prog_ns = self.shell.user_ns
662 __name__save = self.shell.user_ns['__name__']
656 __name__save = self.shell.user_ns['__name__']
663 prog_ns['__name__'] = '__main__'
657 prog_ns['__name__'] = '__main__'
664 main_mod = self.shell.user_module
658 main_mod = self.shell.user_module
665
659
666 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
660 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
667 # set the __file__ global in the script's namespace
661 # set the __file__ global in the script's namespace
668 # TK: Is this necessary in interactive mode?
662 # TK: Is this necessary in interactive mode?
669 prog_ns['__file__'] = filename
663 prog_ns['__file__'] = filename
670 else:
664 else:
671 # Run in a fresh, empty namespace
665 # Run in a fresh, empty namespace
672 if 'n' in opts:
666 if 'n' in opts:
673 name = os.path.splitext(os.path.basename(filename))[0]
667 name = os.path.splitext(os.path.basename(filename))[0]
674 else:
668 else:
675 name = '__main__'
669 name = '__main__'
676
670
677 # The shell MUST hold a reference to prog_ns so after %run
671 # The shell MUST hold a reference to prog_ns so after %run
678 # exits, the python deletion mechanism doesn't zero it out
672 # exits, the python deletion mechanism doesn't zero it out
679 # (leaving dangling references). See interactiveshell for details
673 # (leaving dangling references). See interactiveshell for details
680 main_mod = self.shell.new_main_mod(filename, name)
674 main_mod = self.shell.new_main_mod(filename, name)
681 prog_ns = main_mod.__dict__
675 prog_ns = main_mod.__dict__
682
676
683 # pickle fix. See interactiveshell for an explanation. But we need to
677 # pickle fix. See interactiveshell for an explanation. But we need to
684 # make sure that, if we overwrite __main__, we replace it at the end
678 # make sure that, if we overwrite __main__, we replace it at the end
685 main_mod_name = prog_ns['__name__']
679 main_mod_name = prog_ns['__name__']
686
680
687 if main_mod_name == '__main__':
681 if main_mod_name == '__main__':
688 restore_main = sys.modules['__main__']
682 restore_main = sys.modules['__main__']
689 else:
683 else:
690 restore_main = False
684 restore_main = False
691
685
692 # This needs to be undone at the end to prevent holding references to
686 # This needs to be undone at the end to prevent holding references to
693 # every single object ever created.
687 # every single object ever created.
694 sys.modules[main_mod_name] = main_mod
688 sys.modules[main_mod_name] = main_mod
695
689
696 if 'p' in opts or 'd' in opts:
690 if 'p' in opts or 'd' in opts:
697 if 'm' in opts:
691 if 'm' in opts:
698 code = 'run_module(modulename, prog_ns)'
692 code = 'run_module(modulename, prog_ns)'
699 code_ns = {
693 code_ns = {
700 'run_module': self.shell.safe_run_module,
694 'run_module': self.shell.safe_run_module,
701 'prog_ns': prog_ns,
695 'prog_ns': prog_ns,
702 'modulename': modulename,
696 'modulename': modulename,
703 }
697 }
704 else:
698 else:
705 if 'd' in opts:
699 if 'd' in opts:
706 # allow exceptions to raise in debug mode
700 # allow exceptions to raise in debug mode
707 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
701 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
708 else:
702 else:
709 code = 'execfile(filename, prog_ns)'
703 code = 'execfile(filename, prog_ns)'
710 code_ns = {
704 code_ns = {
711 'execfile': self.shell.safe_execfile,
705 'execfile': self.shell.safe_execfile,
712 'prog_ns': prog_ns,
706 'prog_ns': prog_ns,
713 'filename': get_py_filename(filename),
707 'filename': get_py_filename(filename),
714 }
708 }
715
709
716 try:
710 try:
717 stats = None
711 stats = None
718 if 'p' in opts:
712 if 'p' in opts:
719 stats = self._run_with_profiler(code, opts, code_ns)
713 stats = self._run_with_profiler(code, opts, code_ns)
720 else:
714 else:
721 if 'd' in opts:
715 if 'd' in opts:
722 bp_file, bp_line = parse_breakpoint(
716 bp_file, bp_line = parse_breakpoint(
723 opts.get('b', ['1'])[0], filename)
717 opts.get('b', ['1'])[0], filename)
724 self._run_with_debugger(
718 self._run_with_debugger(
725 code, code_ns, filename, bp_line, bp_file)
719 code, code_ns, filename, bp_line, bp_file)
726 else:
720 else:
727 if 'm' in opts:
721 if 'm' in opts:
728 def run():
722 def run():
729 self.shell.safe_run_module(modulename, prog_ns)
723 self.shell.safe_run_module(modulename, prog_ns)
730 else:
724 else:
731 if runner is None:
725 if runner is None:
732 runner = self.default_runner
726 runner = self.default_runner
733 if runner is None:
727 if runner is None:
734 runner = self.shell.safe_execfile
728 runner = self.shell.safe_execfile
735
729
736 def run():
730 def run():
737 runner(filename, prog_ns, prog_ns,
731 runner(filename, prog_ns, prog_ns,
738 exit_ignore=exit_ignore)
732 exit_ignore=exit_ignore)
739
733
740 if 't' in opts:
734 if 't' in opts:
741 # timed execution
735 # timed execution
742 try:
736 try:
743 nruns = int(opts['N'][0])
737 nruns = int(opts['N'][0])
744 if nruns < 1:
738 if nruns < 1:
745 error('Number of runs must be >=1')
739 error('Number of runs must be >=1')
746 return
740 return
747 except (KeyError):
741 except (KeyError):
748 nruns = 1
742 nruns = 1
749 self._run_with_timing(run, nruns)
743 self._run_with_timing(run, nruns)
750 else:
744 else:
751 # regular execution
745 # regular execution
752 run()
746 run()
753
747
754 if 'i' in opts:
748 if 'i' in opts:
755 self.shell.user_ns['__name__'] = __name__save
749 self.shell.user_ns['__name__'] = __name__save
756 else:
750 else:
757 # update IPython interactive namespace
751 # update IPython interactive namespace
758
752
759 # Some forms of read errors on the file may mean the
753 # Some forms of read errors on the file may mean the
760 # __name__ key was never set; using pop we don't have to
754 # __name__ key was never set; using pop we don't have to
761 # worry about a possible KeyError.
755 # worry about a possible KeyError.
762 prog_ns.pop('__name__', None)
756 prog_ns.pop('__name__', None)
763
757
764 with preserve_keys(self.shell.user_ns, '__file__'):
758 with preserve_keys(self.shell.user_ns, '__file__'):
765 self.shell.user_ns.update(prog_ns)
759 self.shell.user_ns.update(prog_ns)
766 finally:
760 finally:
767 # It's a bit of a mystery why, but __builtins__ can change from
761 # It's a bit of a mystery why, but __builtins__ can change from
768 # being a module to becoming a dict missing some key data after
762 # being a module to becoming a dict missing some key data after
769 # %run. As best I can see, this is NOT something IPython is doing
763 # %run. As best I can see, this is NOT something IPython is doing
770 # at all, and similar problems have been reported before:
764 # at all, and similar problems have been reported before:
771 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
765 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
772 # Since this seems to be done by the interpreter itself, the best
766 # Since this seems to be done by the interpreter itself, the best
773 # we can do is to at least restore __builtins__ for the user on
767 # we can do is to at least restore __builtins__ for the user on
774 # exit.
768 # exit.
775 self.shell.user_ns['__builtins__'] = builtin_mod
769 self.shell.user_ns['__builtins__'] = builtin_mod
776
770
777 # Ensure key global structures are restored
771 # Ensure key global structures are restored
778 sys.argv = save_argv
772 sys.argv = save_argv
779 if restore_main:
773 if restore_main:
780 sys.modules['__main__'] = restore_main
774 sys.modules['__main__'] = restore_main
781 else:
775 else:
782 # Remove from sys.modules the reference to main_mod we'd
776 # Remove from sys.modules the reference to main_mod we'd
783 # added. Otherwise it will trap references to objects
777 # added. Otherwise it will trap references to objects
784 # contained therein.
778 # contained therein.
785 del sys.modules[main_mod_name]
779 del sys.modules[main_mod_name]
786
780
787 return stats
781 return stats
788
782
789 def _run_with_debugger(self, code, code_ns, filename=None,
783 def _run_with_debugger(self, code, code_ns, filename=None,
790 bp_line=None, bp_file=None):
784 bp_line=None, bp_file=None):
791 """
785 """
792 Run `code` in debugger with a break point.
786 Run `code` in debugger with a break point.
793
787
794 Parameters
788 Parameters
795 ----------
789 ----------
796 code : str
790 code : str
797 Code to execute.
791 Code to execute.
798 code_ns : dict
792 code_ns : dict
799 A namespace in which `code` is executed.
793 A namespace in which `code` is executed.
800 filename : str
794 filename : str
801 `code` is ran as if it is in `filename`.
795 `code` is ran as if it is in `filename`.
802 bp_line : int, optional
796 bp_line : int, optional
803 Line number of the break point.
797 Line number of the break point.
804 bp_file : str, optional
798 bp_file : str, optional
805 Path to the file in which break point is specified.
799 Path to the file in which break point is specified.
806 `filename` is used if not given.
800 `filename` is used if not given.
807
801
808 Raises
802 Raises
809 ------
803 ------
810 UsageError
804 UsageError
811 If the break point given by `bp_line` is not valid.
805 If the break point given by `bp_line` is not valid.
812
806
813 """
807 """
814 deb = self.shell.InteractiveTB.pdb
808 deb = self.shell.InteractiveTB.pdb
815 if not deb:
809 if not deb:
816 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
810 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
817 deb = self.shell.InteractiveTB.pdb
811 deb = self.shell.InteractiveTB.pdb
818
812
819 # deb.checkline() fails if deb.curframe exists but is None; it can
813 # deb.checkline() fails if deb.curframe exists but is None; it can
820 # handle it not existing. https://github.com/ipython/ipython/issues/10028
814 # handle it not existing. https://github.com/ipython/ipython/issues/10028
821 if hasattr(deb, 'curframe'):
815 if hasattr(deb, 'curframe'):
822 del deb.curframe
816 del deb.curframe
823
817
824 # reset Breakpoint state, which is moronically kept
818 # reset Breakpoint state, which is moronically kept
825 # in a class
819 # in a class
826 bdb.Breakpoint.next = 1
820 bdb.Breakpoint.next = 1
827 bdb.Breakpoint.bplist = {}
821 bdb.Breakpoint.bplist = {}
828 bdb.Breakpoint.bpbynumber = [None]
822 bdb.Breakpoint.bpbynumber = [None]
829 if bp_line is not None:
823 if bp_line is not None:
830 # Set an initial breakpoint to stop execution
824 # Set an initial breakpoint to stop execution
831 maxtries = 10
825 maxtries = 10
832 bp_file = bp_file or filename
826 bp_file = bp_file or filename
833 checkline = deb.checkline(bp_file, bp_line)
827 checkline = deb.checkline(bp_file, bp_line)
834 if not checkline:
828 if not checkline:
835 for bp in range(bp_line + 1, bp_line + maxtries + 1):
829 for bp in range(bp_line + 1, bp_line + maxtries + 1):
836 if deb.checkline(bp_file, bp):
830 if deb.checkline(bp_file, bp):
837 break
831 break
838 else:
832 else:
839 msg = ("\nI failed to find a valid line to set "
833 msg = ("\nI failed to find a valid line to set "
840 "a breakpoint\n"
834 "a breakpoint\n"
841 "after trying up to line: %s.\n"
835 "after trying up to line: %s.\n"
842 "Please set a valid breakpoint manually "
836 "Please set a valid breakpoint manually "
843 "with the -b option." % bp)
837 "with the -b option." % bp)
844 raise UsageError(msg)
838 raise UsageError(msg)
845 # if we find a good linenumber, set the breakpoint
839 # if we find a good linenumber, set the breakpoint
846 deb.do_break('%s:%s' % (bp_file, bp_line))
840 deb.do_break('%s:%s' % (bp_file, bp_line))
847
841
848 if filename:
842 if filename:
849 # Mimic Pdb._runscript(...)
843 # Mimic Pdb._runscript(...)
850 deb._wait_for_mainpyfile = True
844 deb._wait_for_mainpyfile = True
851 deb.mainpyfile = deb.canonic(filename)
845 deb.mainpyfile = deb.canonic(filename)
852
846
853 # Start file run
847 # Start file run
854 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
848 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
855 try:
849 try:
856 if filename:
850 if filename:
857 # save filename so it can be used by methods on the deb object
851 # save filename so it can be used by methods on the deb object
858 deb._exec_filename = filename
852 deb._exec_filename = filename
859 while True:
853 while True:
860 try:
854 try:
861 deb.run(code, code_ns)
855 deb.run(code, code_ns)
862 except Restart:
856 except Restart:
863 print("Restarting")
857 print("Restarting")
864 if filename:
858 if filename:
865 deb._wait_for_mainpyfile = True
859 deb._wait_for_mainpyfile = True
866 deb.mainpyfile = deb.canonic(filename)
860 deb.mainpyfile = deb.canonic(filename)
867 continue
861 continue
868 else:
862 else:
869 break
863 break
870
864
871
865
872 except:
866 except:
873 etype, value, tb = sys.exc_info()
867 etype, value, tb = sys.exc_info()
874 # Skip three frames in the traceback: the %run one,
868 # Skip three frames in the traceback: the %run one,
875 # one inside bdb.py, and the command-line typed by the
869 # one inside bdb.py, and the command-line typed by the
876 # user (run by exec in pdb itself).
870 # user (run by exec in pdb itself).
877 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
871 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
878
872
879 @staticmethod
873 @staticmethod
880 def _run_with_timing(run, nruns):
874 def _run_with_timing(run, nruns):
881 """
875 """
882 Run function `run` and print timing information.
876 Run function `run` and print timing information.
883
877
884 Parameters
878 Parameters
885 ----------
879 ----------
886 run : callable
880 run : callable
887 Any callable object which takes no argument.
881 Any callable object which takes no argument.
888 nruns : int
882 nruns : int
889 Number of times to execute `run`.
883 Number of times to execute `run`.
890
884
891 """
885 """
892 twall0 = time.time()
886 twall0 = time.time()
893 if nruns == 1:
887 if nruns == 1:
894 t0 = clock2()
888 t0 = clock2()
895 run()
889 run()
896 t1 = clock2()
890 t1 = clock2()
897 t_usr = t1[0] - t0[0]
891 t_usr = t1[0] - t0[0]
898 t_sys = t1[1] - t0[1]
892 t_sys = t1[1] - t0[1]
899 print("\nIPython CPU timings (estimated):")
893 print("\nIPython CPU timings (estimated):")
900 print(" User : %10.2f s." % t_usr)
894 print(" User : %10.2f s." % t_usr)
901 print(" System : %10.2f s." % t_sys)
895 print(" System : %10.2f s." % t_sys)
902 else:
896 else:
903 runs = range(nruns)
897 runs = range(nruns)
904 t0 = clock2()
898 t0 = clock2()
905 for nr in runs:
899 for nr in runs:
906 run()
900 run()
907 t1 = clock2()
901 t1 = clock2()
908 t_usr = t1[0] - t0[0]
902 t_usr = t1[0] - t0[0]
909 t_sys = t1[1] - t0[1]
903 t_sys = t1[1] - t0[1]
910 print("\nIPython CPU timings (estimated):")
904 print("\nIPython CPU timings (estimated):")
911 print("Total runs performed:", nruns)
905 print("Total runs performed:", nruns)
912 print(" Times : %10s %10s" % ('Total', 'Per run'))
906 print(" Times : %10s %10s" % ('Total', 'Per run'))
913 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
907 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
914 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
908 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
915 twall1 = time.time()
909 twall1 = time.time()
916 print("Wall time: %10.2f s." % (twall1 - twall0))
910 print("Wall time: %10.2f s." % (twall1 - twall0))
917
911
918 @skip_doctest
912 @skip_doctest
919 @line_cell_magic
913 @line_cell_magic
920 def timeit(self, line='', cell=None):
914 def timeit(self, line='', cell=None):
921 """Time execution of a Python statement or expression
915 """Time execution of a Python statement or expression
922
916
923 Usage, in line mode:
917 Usage, in line mode:
924 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
918 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
925 or in cell mode:
919 or in cell mode:
926 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
920 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
927 code
921 code
928 code...
922 code...
929
923
930 Time execution of a Python statement or expression using the timeit
924 Time execution of a Python statement or expression using the timeit
931 module. This function can be used both as a line and cell magic:
925 module. This function can be used both as a line and cell magic:
932
926
933 - In line mode you can time a single-line statement (though multiple
927 - In line mode you can time a single-line statement (though multiple
934 ones can be chained with using semicolons).
928 ones can be chained with using semicolons).
935
929
936 - In cell mode, the statement in the first line is used as setup code
930 - In cell mode, the statement in the first line is used as setup code
937 (executed but not timed) and the body of the cell is timed. The cell
931 (executed but not timed) and the body of the cell is timed. The cell
938 body has access to any variables created in the setup code.
932 body has access to any variables created in the setup code.
939
933
940 Options:
934 Options:
941 -n<N>: execute the given statement <N> times in a loop. If this value
935 -n<N>: execute the given statement <N> times in a loop. If this value
942 is not given, a fitting value is chosen.
936 is not given, a fitting value is chosen.
943
937
944 -r<R>: repeat the loop iteration <R> times and take the best result.
938 -r<R>: repeat the loop iteration <R> times and take the best result.
945 Default: 3
939 Default: 3
946
940
947 -t: use time.time to measure the time, which is the default on Unix.
941 -t: use time.time to measure the time, which is the default on Unix.
948 This function measures wall time.
942 This function measures wall time.
949
943
950 -c: use time.clock to measure the time, which is the default on
944 -c: use time.clock to measure the time, which is the default on
951 Windows and measures wall time. On Unix, resource.getrusage is used
945 Windows and measures wall time. On Unix, resource.getrusage is used
952 instead and returns the CPU user time.
946 instead and returns the CPU user time.
953
947
954 -p<P>: use a precision of <P> digits to display the timing result.
948 -p<P>: use a precision of <P> digits to display the timing result.
955 Default: 3
949 Default: 3
956
950
957 -q: Quiet, do not print result.
951 -q: Quiet, do not print result.
958
952
959 -o: return a TimeitResult that can be stored in a variable to inspect
953 -o: return a TimeitResult that can be stored in a variable to inspect
960 the result in more details.
954 the result in more details.
961
955
962
956
963 Examples
957 Examples
964 --------
958 --------
965 ::
959 ::
966
960
967 In [1]: %timeit pass
961 In [1]: %timeit pass
968 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
962 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
969
963
970 In [2]: u = None
964 In [2]: u = None
971
965
972 In [3]: %timeit u is None
966 In [3]: %timeit u is None
973 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
967 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
974
968
975 In [4]: %timeit -r 4 u == None
969 In [4]: %timeit -r 4 u == None
976 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
970 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
977
971
978 In [5]: import time
972 In [5]: import time
979
973
980 In [6]: %timeit -n1 time.sleep(2)
974 In [6]: %timeit -n1 time.sleep(2)
981 1 loop, average of 7: 2 s +- 4.71 Β΅s per loop (using standard deviation)
975 1 loop, average of 7: 2 s +- 4.71 Β΅s per loop (using standard deviation)
982
976
983
977
984 The times reported by %timeit will be slightly higher than those
978 The times reported by %timeit will be slightly higher than those
985 reported by the timeit.py script when variables are accessed. This is
979 reported by the timeit.py script when variables are accessed. This is
986 due to the fact that %timeit executes the statement in the namespace
980 due to the fact that %timeit executes the statement in the namespace
987 of the shell, compared with timeit.py, which uses a single setup
981 of the shell, compared with timeit.py, which uses a single setup
988 statement to import function or create variables. Generally, the bias
982 statement to import function or create variables. Generally, the bias
989 does not matter as long as results from timeit.py are not mixed with
983 does not matter as long as results from timeit.py are not mixed with
990 those from %timeit."""
984 those from %timeit."""
991
985
992 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
986 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
993 posix=False, strict=False)
987 posix=False, strict=False)
994 if stmt == "" and cell is None:
988 if stmt == "" and cell is None:
995 return
989 return
996
990
997 timefunc = timeit.default_timer
991 timefunc = timeit.default_timer
998 number = int(getattr(opts, "n", 0))
992 number = int(getattr(opts, "n", 0))
999 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
993 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1000 repeat = int(getattr(opts, "r", default_repeat))
994 repeat = int(getattr(opts, "r", default_repeat))
1001 precision = int(getattr(opts, "p", 3))
995 precision = int(getattr(opts, "p", 3))
1002 quiet = 'q' in opts
996 quiet = 'q' in opts
1003 return_result = 'o' in opts
997 return_result = 'o' in opts
1004 if hasattr(opts, "t"):
998 if hasattr(opts, "t"):
1005 timefunc = time.time
999 timefunc = time.time
1006 if hasattr(opts, "c"):
1000 if hasattr(opts, "c"):
1007 timefunc = clock
1001 timefunc = clock
1008
1002
1009 timer = Timer(timer=timefunc)
1003 timer = Timer(timer=timefunc)
1010 # this code has tight coupling to the inner workings of timeit.Timer,
1004 # this code has tight coupling to the inner workings of timeit.Timer,
1011 # but is there a better way to achieve that the code stmt has access
1005 # but is there a better way to achieve that the code stmt has access
1012 # to the shell namespace?
1006 # to the shell namespace?
1013 transform = self.shell.input_splitter.transform_cell
1007 transform = self.shell.input_splitter.transform_cell
1014
1008
1015 if cell is None:
1009 if cell is None:
1016 # called as line magic
1010 # called as line magic
1017 ast_setup = self.shell.compile.ast_parse("pass")
1011 ast_setup = self.shell.compile.ast_parse("pass")
1018 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1012 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1019 else:
1013 else:
1020 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1014 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1021 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1015 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1022
1016
1023 ast_setup = self.shell.transform_ast(ast_setup)
1017 ast_setup = self.shell.transform_ast(ast_setup)
1024 ast_stmt = self.shell.transform_ast(ast_stmt)
1018 ast_stmt = self.shell.transform_ast(ast_stmt)
1025
1019
1026 # This codestring is taken from timeit.template - we fill it in as an
1020 # This codestring is taken from timeit.template - we fill it in as an
1027 # AST, so that we can apply our AST transformations to the user code
1021 # AST, so that we can apply our AST transformations to the user code
1028 # without affecting the timing code.
1022 # without affecting the timing code.
1029 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1023 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1030 ' setup\n'
1024 ' setup\n'
1031 ' _t0 = _timer()\n'
1025 ' _t0 = _timer()\n'
1032 ' for _i in _it:\n'
1026 ' for _i in _it:\n'
1033 ' stmt\n'
1027 ' stmt\n'
1034 ' _t1 = _timer()\n'
1028 ' _t1 = _timer()\n'
1035 ' return _t1 - _t0\n')
1029 ' return _t1 - _t0\n')
1036
1030
1037 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1031 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1038 timeit_ast = ast.fix_missing_locations(timeit_ast)
1032 timeit_ast = ast.fix_missing_locations(timeit_ast)
1039
1033
1040 # Track compilation time so it can be reported if too long
1034 # Track compilation time so it can be reported if too long
1041 # Minimum time above which compilation time will be reported
1035 # Minimum time above which compilation time will be reported
1042 tc_min = 0.1
1036 tc_min = 0.1
1043
1037
1044 t0 = clock()
1038 t0 = clock()
1045 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1039 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1046 tc = clock()-t0
1040 tc = clock()-t0
1047
1041
1048 ns = {}
1042 ns = {}
1049 exec(code, self.shell.user_ns, ns)
1043 exec(code, self.shell.user_ns, ns)
1050 timer.inner = ns["inner"]
1044 timer.inner = ns["inner"]
1051
1045
1052 # This is used to check if there is a huge difference between the
1046 # This is used to check if there is a huge difference between the
1053 # best and worst timings.
1047 # best and worst timings.
1054 # Issue: https://github.com/ipython/ipython/issues/6471
1048 # Issue: https://github.com/ipython/ipython/issues/6471
1055 if number == 0:
1049 if number == 0:
1056 # determine number so that 0.2 <= total time < 2.0
1050 # determine number so that 0.2 <= total time < 2.0
1057 for index in range(0, 10):
1051 for index in range(0, 10):
1058 number = 10 ** index
1052 number = 10 ** index
1059 time_number = timer.timeit(number)
1053 time_number = timer.timeit(number)
1060 if time_number >= 0.2:
1054 if time_number >= 0.2:
1061 break
1055 break
1062
1056
1063 all_runs = timer.repeat(repeat, number)
1057 all_runs = timer.repeat(repeat, number)
1064 best = min(all_runs) / number
1058 best = min(all_runs) / number
1065 worst = max(all_runs) / number
1059 worst = max(all_runs) / number
1066 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1060 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1067
1061
1068 if not quiet :
1062 if not quiet :
1069 # Check best timing is greater than zero to avoid a
1063 # Check best timing is greater than zero to avoid a
1070 # ZeroDivisionError.
1064 # ZeroDivisionError.
1071 # In cases where the slowest timing is lesser than a micosecond
1065 # In cases where the slowest timing is lesser than a micosecond
1072 # we assume that it does not really matter if the fastest
1066 # we assume that it does not really matter if the fastest
1073 # timing is 4 times faster than the slowest timing or not.
1067 # timing is 4 times faster than the slowest timing or not.
1074 if worst > 4 * best and best > 0 and worst > 1e-6:
1068 if worst > 4 * best and best > 0 and worst > 1e-6:
1075 print("The slowest run took %0.2f times longer than the "
1069 print("The slowest run took %0.2f times longer than the "
1076 "fastest. This could mean that an intermediate result "
1070 "fastest. This could mean that an intermediate result "
1077 "is being cached." % (worst / best))
1071 "is being cached." % (worst / best))
1078
1072
1079 print( timeit_result )
1073 print( timeit_result )
1080
1074
1081 if tc > tc_min:
1075 if tc > tc_min:
1082 print("Compiler time: %.2f s" % tc)
1076 print("Compiler time: %.2f s" % tc)
1083 if return_result:
1077 if return_result:
1084 return timeit_result
1078 return timeit_result
1085
1079
1086 @skip_doctest
1080 @skip_doctest
1087 @needs_local_scope
1081 @needs_local_scope
1088 @line_cell_magic
1082 @line_cell_magic
1089 def time(self,line='', cell=None, local_ns=None):
1083 def time(self,line='', cell=None, local_ns=None):
1090 """Time execution of a Python statement or expression.
1084 """Time execution of a Python statement or expression.
1091
1085
1092 The CPU and wall clock times are printed, and the value of the
1086 The CPU and wall clock times are printed, and the value of the
1093 expression (if any) is returned. Note that under Win32, system time
1087 expression (if any) is returned. Note that under Win32, system time
1094 is always reported as 0, since it can not be measured.
1088 is always reported as 0, since it can not be measured.
1095
1089
1096 This function can be used both as a line and cell magic:
1090 This function can be used both as a line and cell magic:
1097
1091
1098 - In line mode you can time a single-line statement (though multiple
1092 - In line mode you can time a single-line statement (though multiple
1099 ones can be chained with using semicolons).
1093 ones can be chained with using semicolons).
1100
1094
1101 - In cell mode, you can time the cell body (a directly
1095 - In cell mode, you can time the cell body (a directly
1102 following statement raises an error).
1096 following statement raises an error).
1103
1097
1104 This function provides very basic timing functionality. Use the timeit
1098 This function provides very basic timing functionality. Use the timeit
1105 magic for more control over the measurement.
1099 magic for more control over the measurement.
1106
1100
1107 Examples
1101 Examples
1108 --------
1102 --------
1109 ::
1103 ::
1110
1104
1111 In [1]: %time 2**128
1105 In [1]: %time 2**128
1112 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1106 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1113 Wall time: 0.00
1107 Wall time: 0.00
1114 Out[1]: 340282366920938463463374607431768211456L
1108 Out[1]: 340282366920938463463374607431768211456L
1115
1109
1116 In [2]: n = 1000000
1110 In [2]: n = 1000000
1117
1111
1118 In [3]: %time sum(range(n))
1112 In [3]: %time sum(range(n))
1119 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1113 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1120 Wall time: 1.37
1114 Wall time: 1.37
1121 Out[3]: 499999500000L
1115 Out[3]: 499999500000L
1122
1116
1123 In [4]: %time print 'hello world'
1117 In [4]: %time print 'hello world'
1124 hello world
1118 hello world
1125 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1119 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1126 Wall time: 0.00
1120 Wall time: 0.00
1127
1121
1128 Note that the time needed by Python to compile the given expression
1122 Note that the time needed by Python to compile the given expression
1129 will be reported if it is more than 0.1s. In this example, the
1123 will be reported if it is more than 0.1s. In this example, the
1130 actual exponentiation is done by Python at compilation time, so while
1124 actual exponentiation is done by Python at compilation time, so while
1131 the expression can take a noticeable amount of time to compute, that
1125 the expression can take a noticeable amount of time to compute, that
1132 time is purely due to the compilation:
1126 time is purely due to the compilation:
1133
1127
1134 In [5]: %time 3**9999;
1128 In [5]: %time 3**9999;
1135 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1129 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1136 Wall time: 0.00 s
1130 Wall time: 0.00 s
1137
1131
1138 In [6]: %time 3**999999;
1132 In [6]: %time 3**999999;
1139 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1133 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1140 Wall time: 0.00 s
1134 Wall time: 0.00 s
1141 Compiler : 0.78 s
1135 Compiler : 0.78 s
1142 """
1136 """
1143
1137
1144 # fail immediately if the given expression can't be compiled
1138 # fail immediately if the given expression can't be compiled
1145
1139
1146 if line and cell:
1140 if line and cell:
1147 raise UsageError("Can't use statement directly after '%%time'!")
1141 raise UsageError("Can't use statement directly after '%%time'!")
1148
1142
1149 if cell:
1143 if cell:
1150 expr = self.shell.input_transformer_manager.transform_cell(cell)
1144 expr = self.shell.input_transformer_manager.transform_cell(cell)
1151 else:
1145 else:
1152 expr = self.shell.input_transformer_manager.transform_cell(line)
1146 expr = self.shell.input_transformer_manager.transform_cell(line)
1153
1147
1154 # Minimum time above which parse time will be reported
1148 # Minimum time above which parse time will be reported
1155 tp_min = 0.1
1149 tp_min = 0.1
1156
1150
1157 t0 = clock()
1151 t0 = clock()
1158 expr_ast = self.shell.compile.ast_parse(expr)
1152 expr_ast = self.shell.compile.ast_parse(expr)
1159 tp = clock()-t0
1153 tp = clock()-t0
1160
1154
1161 # Apply AST transformations
1155 # Apply AST transformations
1162 expr_ast = self.shell.transform_ast(expr_ast)
1156 expr_ast = self.shell.transform_ast(expr_ast)
1163
1157
1164 # Minimum time above which compilation time will be reported
1158 # Minimum time above which compilation time will be reported
1165 tc_min = 0.1
1159 tc_min = 0.1
1166
1160
1167 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1161 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1168 mode = 'eval'
1162 mode = 'eval'
1169 source = '<timed eval>'
1163 source = '<timed eval>'
1170 expr_ast = ast.Expression(expr_ast.body[0].value)
1164 expr_ast = ast.Expression(expr_ast.body[0].value)
1171 else:
1165 else:
1172 mode = 'exec'
1166 mode = 'exec'
1173 source = '<timed exec>'
1167 source = '<timed exec>'
1174 t0 = clock()
1168 t0 = clock()
1175 code = self.shell.compile(expr_ast, source, mode)
1169 code = self.shell.compile(expr_ast, source, mode)
1176 tc = clock()-t0
1170 tc = clock()-t0
1177
1171
1178 # skew measurement as little as possible
1172 # skew measurement as little as possible
1179 glob = self.shell.user_ns
1173 glob = self.shell.user_ns
1180 wtime = time.time
1174 wtime = time.time
1181 # time execution
1175 # time execution
1182 wall_st = wtime()
1176 wall_st = wtime()
1183 if mode=='eval':
1177 if mode=='eval':
1184 st = clock2()
1178 st = clock2()
1185 try:
1179 try:
1186 out = eval(code, glob, local_ns)
1180 out = eval(code, glob, local_ns)
1187 except:
1181 except:
1188 self.shell.showtraceback()
1182 self.shell.showtraceback()
1189 return
1183 return
1190 end = clock2()
1184 end = clock2()
1191 else:
1185 else:
1192 st = clock2()
1186 st = clock2()
1193 try:
1187 try:
1194 exec(code, glob, local_ns)
1188 exec(code, glob, local_ns)
1195 except:
1189 except:
1196 self.shell.showtraceback()
1190 self.shell.showtraceback()
1197 return
1191 return
1198 end = clock2()
1192 end = clock2()
1199 out = None
1193 out = None
1200 wall_end = wtime()
1194 wall_end = wtime()
1201 # Compute actual times and report
1195 # Compute actual times and report
1202 wall_time = wall_end-wall_st
1196 wall_time = wall_end-wall_st
1203 cpu_user = end[0]-st[0]
1197 cpu_user = end[0]-st[0]
1204 cpu_sys = end[1]-st[1]
1198 cpu_sys = end[1]-st[1]
1205 cpu_tot = cpu_user+cpu_sys
1199 cpu_tot = cpu_user+cpu_sys
1206 # On windows cpu_sys is always zero, so no new information to the next print
1200 # On windows cpu_sys is always zero, so no new information to the next print
1207 if sys.platform != 'win32':
1201 if sys.platform != 'win32':
1208 print("CPU times: user %s, sys: %s, total: %s" % \
1202 print("CPU times: user %s, sys: %s, total: %s" % \
1209 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1203 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1210 print("Wall time: %s" % _format_time(wall_time))
1204 print("Wall time: %s" % _format_time(wall_time))
1211 if tc > tc_min:
1205 if tc > tc_min:
1212 print("Compiler : %s" % _format_time(tc))
1206 print("Compiler : %s" % _format_time(tc))
1213 if tp > tp_min:
1207 if tp > tp_min:
1214 print("Parser : %s" % _format_time(tp))
1208 print("Parser : %s" % _format_time(tp))
1215 return out
1209 return out
1216
1210
1217 @skip_doctest
1211 @skip_doctest
1218 @line_magic
1212 @line_magic
1219 def macro(self, parameter_s=''):
1213 def macro(self, parameter_s=''):
1220 """Define a macro for future re-execution. It accepts ranges of history,
1214 """Define a macro for future re-execution. It accepts ranges of history,
1221 filenames or string objects.
1215 filenames or string objects.
1222
1216
1223 Usage:\\
1217 Usage:\\
1224 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1218 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1225
1219
1226 Options:
1220 Options:
1227
1221
1228 -r: use 'raw' input. By default, the 'processed' history is used,
1222 -r: use 'raw' input. By default, the 'processed' history is used,
1229 so that magics are loaded in their transformed version to valid
1223 so that magics are loaded in their transformed version to valid
1230 Python. If this option is given, the raw input as typed at the
1224 Python. If this option is given, the raw input as typed at the
1231 command line is used instead.
1225 command line is used instead.
1232
1226
1233 -q: quiet macro definition. By default, a tag line is printed
1227 -q: quiet macro definition. By default, a tag line is printed
1234 to indicate the macro has been created, and then the contents of
1228 to indicate the macro has been created, and then the contents of
1235 the macro are printed. If this option is given, then no printout
1229 the macro are printed. If this option is given, then no printout
1236 is produced once the macro is created.
1230 is produced once the macro is created.
1237
1231
1238 This will define a global variable called `name` which is a string
1232 This will define a global variable called `name` which is a string
1239 made of joining the slices and lines you specify (n1,n2,... numbers
1233 made of joining the slices and lines you specify (n1,n2,... numbers
1240 above) from your input history into a single string. This variable
1234 above) from your input history into a single string. This variable
1241 acts like an automatic function which re-executes those lines as if
1235 acts like an automatic function which re-executes those lines as if
1242 you had typed them. You just type 'name' at the prompt and the code
1236 you had typed them. You just type 'name' at the prompt and the code
1243 executes.
1237 executes.
1244
1238
1245 The syntax for indicating input ranges is described in %history.
1239 The syntax for indicating input ranges is described in %history.
1246
1240
1247 Note: as a 'hidden' feature, you can also use traditional python slice
1241 Note: as a 'hidden' feature, you can also use traditional python slice
1248 notation, where N:M means numbers N through M-1.
1242 notation, where N:M means numbers N through M-1.
1249
1243
1250 For example, if your history contains (print using %hist -n )::
1244 For example, if your history contains (print using %hist -n )::
1251
1245
1252 44: x=1
1246 44: x=1
1253 45: y=3
1247 45: y=3
1254 46: z=x+y
1248 46: z=x+y
1255 47: print x
1249 47: print x
1256 48: a=5
1250 48: a=5
1257 49: print 'x',x,'y',y
1251 49: print 'x',x,'y',y
1258
1252
1259 you can create a macro with lines 44 through 47 (included) and line 49
1253 you can create a macro with lines 44 through 47 (included) and line 49
1260 called my_macro with::
1254 called my_macro with::
1261
1255
1262 In [55]: %macro my_macro 44-47 49
1256 In [55]: %macro my_macro 44-47 49
1263
1257
1264 Now, typing `my_macro` (without quotes) will re-execute all this code
1258 Now, typing `my_macro` (without quotes) will re-execute all this code
1265 in one pass.
1259 in one pass.
1266
1260
1267 You don't need to give the line-numbers in order, and any given line
1261 You don't need to give the line-numbers in order, and any given line
1268 number can appear multiple times. You can assemble macros with any
1262 number can appear multiple times. You can assemble macros with any
1269 lines from your input history in any order.
1263 lines from your input history in any order.
1270
1264
1271 The macro is a simple object which holds its value in an attribute,
1265 The macro is a simple object which holds its value in an attribute,
1272 but IPython's display system checks for macros and executes them as
1266 but IPython's display system checks for macros and executes them as
1273 code instead of printing them when you type their name.
1267 code instead of printing them when you type their name.
1274
1268
1275 You can view a macro's contents by explicitly printing it with::
1269 You can view a macro's contents by explicitly printing it with::
1276
1270
1277 print macro_name
1271 print macro_name
1278
1272
1279 """
1273 """
1280 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1274 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1281 if not args: # List existing macros
1275 if not args: # List existing macros
1282 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1276 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1283 if len(args) == 1:
1277 if len(args) == 1:
1284 raise UsageError(
1278 raise UsageError(
1285 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1279 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1286 name, codefrom = args[0], " ".join(args[1:])
1280 name, codefrom = args[0], " ".join(args[1:])
1287
1281
1288 #print 'rng',ranges # dbg
1282 #print 'rng',ranges # dbg
1289 try:
1283 try:
1290 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1284 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1291 except (ValueError, TypeError) as e:
1285 except (ValueError, TypeError) as e:
1292 print(e.args[0])
1286 print(e.args[0])
1293 return
1287 return
1294 macro = Macro(lines)
1288 macro = Macro(lines)
1295 self.shell.define_macro(name, macro)
1289 self.shell.define_macro(name, macro)
1296 if not ( 'q' in opts) :
1290 if not ( 'q' in opts) :
1297 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1291 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1298 print('=== Macro contents: ===')
1292 print('=== Macro contents: ===')
1299 print(macro, end=' ')
1293 print(macro, end=' ')
1300
1294
1301 @magic_arguments.magic_arguments()
1295 @magic_arguments.magic_arguments()
1302 @magic_arguments.argument('output', type=str, default='', nargs='?',
1296 @magic_arguments.argument('output', type=str, default='', nargs='?',
1303 help="""The name of the variable in which to store output.
1297 help="""The name of the variable in which to store output.
1304 This is a utils.io.CapturedIO object with stdout/err attributes
1298 This is a utils.io.CapturedIO object with stdout/err attributes
1305 for the text of the captured output.
1299 for the text of the captured output.
1306
1300
1307 CapturedOutput also has a show() method for displaying the output,
1301 CapturedOutput also has a show() method for displaying the output,
1308 and __call__ as well, so you can use that to quickly display the
1302 and __call__ as well, so you can use that to quickly display the
1309 output.
1303 output.
1310
1304
1311 If unspecified, captured output is discarded.
1305 If unspecified, captured output is discarded.
1312 """
1306 """
1313 )
1307 )
1314 @magic_arguments.argument('--no-stderr', action="store_true",
1308 @magic_arguments.argument('--no-stderr', action="store_true",
1315 help="""Don't capture stderr."""
1309 help="""Don't capture stderr."""
1316 )
1310 )
1317 @magic_arguments.argument('--no-stdout', action="store_true",
1311 @magic_arguments.argument('--no-stdout', action="store_true",
1318 help="""Don't capture stdout."""
1312 help="""Don't capture stdout."""
1319 )
1313 )
1320 @magic_arguments.argument('--no-display', action="store_true",
1314 @magic_arguments.argument('--no-display', action="store_true",
1321 help="""Don't capture IPython's rich display."""
1315 help="""Don't capture IPython's rich display."""
1322 )
1316 )
1323 @cell_magic
1317 @cell_magic
1324 def capture(self, line, cell):
1318 def capture(self, line, cell):
1325 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1319 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1326 args = magic_arguments.parse_argstring(self.capture, line)
1320 args = magic_arguments.parse_argstring(self.capture, line)
1327 out = not args.no_stdout
1321 out = not args.no_stdout
1328 err = not args.no_stderr
1322 err = not args.no_stderr
1329 disp = not args.no_display
1323 disp = not args.no_display
1330 with capture_output(out, err, disp) as io:
1324 with capture_output(out, err, disp) as io:
1331 self.shell.run_cell(cell)
1325 self.shell.run_cell(cell)
1332 if args.output:
1326 if args.output:
1333 self.shell.user_ns[args.output] = io
1327 self.shell.user_ns[args.output] = io
1334
1328
1335 def parse_breakpoint(text, current_file):
1329 def parse_breakpoint(text, current_file):
1336 '''Returns (file, line) for file:line and (current_file, line) for line'''
1330 '''Returns (file, line) for file:line and (current_file, line) for line'''
1337 colon = text.find(':')
1331 colon = text.find(':')
1338 if colon == -1:
1332 if colon == -1:
1339 return current_file, int(text)
1333 return current_file, int(text)
1340 else:
1334 else:
1341 return text[:colon], int(text[colon+1:])
1335 return text[:colon], int(text[colon+1:])
1342
1336
1343 def _format_time(timespan, precision=3):
1337 def _format_time(timespan, precision=3):
1344 """Formats the timespan in a human readable form"""
1338 """Formats the timespan in a human readable form"""
1345
1339
1346 if timespan >= 60.0:
1340 if timespan >= 60.0:
1347 # we have more than a minute, format that in a human readable form
1341 # we have more than a minute, format that in a human readable form
1348 # Idea from http://snipplr.com/view/5713/
1342 # Idea from http://snipplr.com/view/5713/
1349 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1343 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1350 time = []
1344 time = []
1351 leftover = timespan
1345 leftover = timespan
1352 for suffix, length in parts:
1346 for suffix, length in parts:
1353 value = int(leftover / length)
1347 value = int(leftover / length)
1354 if value > 0:
1348 if value > 0:
1355 leftover = leftover % length
1349 leftover = leftover % length
1356 time.append(u'%s%s' % (str(value), suffix))
1350 time.append(u'%s%s' % (str(value), suffix))
1357 if leftover < 1:
1351 if leftover < 1:
1358 break
1352 break
1359 return " ".join(time)
1353 return " ".join(time)
1360
1354
1361
1355
1362 # Unfortunately the unicode 'micro' symbol can cause problems in
1356 # Unfortunately the unicode 'micro' symbol can cause problems in
1363 # certain terminals.
1357 # certain terminals.
1364 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1358 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1365 # Try to prevent crashes by being more secure than it needs to
1359 # Try to prevent crashes by being more secure than it needs to
1366 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1360 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1367 units = [u"s", u"ms",u'us',"ns"] # the save value
1361 units = [u"s", u"ms",u'us',"ns"] # the save value
1368 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1362 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1369 try:
1363 try:
1370 u'\xb5'.encode(sys.stdout.encoding)
1364 u'\xb5'.encode(sys.stdout.encoding)
1371 units = [u"s", u"ms",u'\xb5s',"ns"]
1365 units = [u"s", u"ms",u'\xb5s',"ns"]
1372 except:
1366 except:
1373 pass
1367 pass
1374 scaling = [1, 1e3, 1e6, 1e9]
1368 scaling = [1, 1e3, 1e6, 1e9]
1375
1369
1376 if timespan > 0.0:
1370 if timespan > 0.0:
1377 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1371 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1378 else:
1372 else:
1379 order = 3
1373 order = 3
1380 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1374 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,408 +1,405 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5 """
5 """
6
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 import glob
10 import glob
11 import os
11 import os
12 import sys
12 import sys
13
13
14 from traitlets.config.application import boolean_flag
14 from traitlets.config.application import boolean_flag
15 from traitlets.config.configurable import Configurable
15 from traitlets.config.configurable import Configurable
16 from traitlets.config.loader import Config
16 from traitlets.config.loader import Config
17 from IPython.core import pylabtools
17 from IPython.core import pylabtools
18 from IPython.utils import py3compat
18 from IPython.utils import py3compat
19 from IPython.utils.contexts import preserve_keys
19 from IPython.utils.contexts import preserve_keys
20 from IPython.utils.path import filefind
20 from IPython.utils.path import filefind
21 from traitlets import (
21 from traitlets import (
22 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
22 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
23 )
23 )
24 from IPython.terminal import pt_inputhooks
24 from IPython.terminal import pt_inputhooks
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Aliases and Flags
27 # Aliases and Flags
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
30 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
31
31
32 backend_keys = sorted(pylabtools.backends.keys())
32 backend_keys = sorted(pylabtools.backends.keys())
33 backend_keys.insert(0, 'auto')
33 backend_keys.insert(0, 'auto')
34
34
35 shell_flags = {}
35 shell_flags = {}
36
36
37 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
37 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
38 addflag('autoindent', 'InteractiveShell.autoindent',
38 addflag('autoindent', 'InteractiveShell.autoindent',
39 'Turn on autoindenting.', 'Turn off autoindenting.'
39 'Turn on autoindenting.', 'Turn off autoindenting.'
40 )
40 )
41 addflag('automagic', 'InteractiveShell.automagic',
41 addflag('automagic', 'InteractiveShell.automagic',
42 """Turn on the auto calling of magic commands. Type %%magic at the
42 """Turn on the auto calling of magic commands. Type %%magic at the
43 IPython prompt for more information.""",
43 IPython prompt for more information.""",
44 'Turn off the auto calling of magic commands.'
44 'Turn off the auto calling of magic commands.'
45 )
45 )
46 addflag('pdb', 'InteractiveShell.pdb',
46 addflag('pdb', 'InteractiveShell.pdb',
47 "Enable auto calling the pdb debugger after every exception.",
47 "Enable auto calling the pdb debugger after every exception.",
48 "Disable auto calling the pdb debugger after every exception."
48 "Disable auto calling the pdb debugger after every exception."
49 )
49 )
50 addflag('pprint', 'PlainTextFormatter.pprint',
50 addflag('pprint', 'PlainTextFormatter.pprint',
51 "Enable auto pretty printing of results.",
51 "Enable auto pretty printing of results.",
52 "Disable auto pretty printing of results."
52 "Disable auto pretty printing of results."
53 )
53 )
54 addflag('color-info', 'InteractiveShell.color_info',
54 addflag('color-info', 'InteractiveShell.color_info',
55 """IPython can display information about objects via a set of functions,
55 """IPython can display information about objects via a set of functions,
56 and optionally can use colors for this, syntax highlighting
56 and optionally can use colors for this, syntax highlighting
57 source code and various other elements. This is on by default, but can cause
57 source code and various other elements. This is on by default, but can cause
58 problems with some pagers. If you see such problems, you can disable the
58 problems with some pagers. If you see such problems, you can disable the
59 colours.""",
59 colours.""",
60 "Disable using colors for info related things."
60 "Disable using colors for info related things."
61 )
61 )
62 nosep_config = Config()
62 nosep_config = Config()
63 nosep_config.InteractiveShell.separate_in = ''
63 nosep_config.InteractiveShell.separate_in = ''
64 nosep_config.InteractiveShell.separate_out = ''
64 nosep_config.InteractiveShell.separate_out = ''
65 nosep_config.InteractiveShell.separate_out2 = ''
65 nosep_config.InteractiveShell.separate_out2 = ''
66
66
67 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
67 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
68 shell_flags['pylab'] = (
68 shell_flags['pylab'] = (
69 {'InteractiveShellApp' : {'pylab' : 'auto'}},
69 {'InteractiveShellApp' : {'pylab' : 'auto'}},
70 """Pre-load matplotlib and numpy for interactive use with
70 """Pre-load matplotlib and numpy for interactive use with
71 the default matplotlib backend."""
71 the default matplotlib backend."""
72 )
72 )
73 shell_flags['matplotlib'] = (
73 shell_flags['matplotlib'] = (
74 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
74 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
75 """Configure matplotlib for interactive use with
75 """Configure matplotlib for interactive use with
76 the default matplotlib backend."""
76 the default matplotlib backend."""
77 )
77 )
78
78
79 # it's possible we don't want short aliases for *all* of these:
79 # it's possible we don't want short aliases for *all* of these:
80 shell_aliases = dict(
80 shell_aliases = dict(
81 autocall='InteractiveShell.autocall',
81 autocall='InteractiveShell.autocall',
82 colors='InteractiveShell.colors',
82 colors='InteractiveShell.colors',
83 logfile='InteractiveShell.logfile',
83 logfile='InteractiveShell.logfile',
84 logappend='InteractiveShell.logappend',
84 logappend='InteractiveShell.logappend',
85 c='InteractiveShellApp.code_to_run',
85 c='InteractiveShellApp.code_to_run',
86 m='InteractiveShellApp.module_to_run',
86 m='InteractiveShellApp.module_to_run',
87 ext='InteractiveShellApp.extra_extension',
87 ext='InteractiveShellApp.extra_extension',
88 gui='InteractiveShellApp.gui',
88 gui='InteractiveShellApp.gui',
89 pylab='InteractiveShellApp.pylab',
89 pylab='InteractiveShellApp.pylab',
90 matplotlib='InteractiveShellApp.matplotlib',
90 matplotlib='InteractiveShellApp.matplotlib',
91 )
91 )
92 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
92 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Main classes and functions
95 # Main classes and functions
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97
97
98 class InteractiveShellApp(Configurable):
98 class InteractiveShellApp(Configurable):
99 """A Mixin for applications that start InteractiveShell instances.
99 """A Mixin for applications that start InteractiveShell instances.
100
100
101 Provides configurables for loading extensions and executing files
101 Provides configurables for loading extensions and executing files
102 as part of configuring a Shell environment.
102 as part of configuring a Shell environment.
103
103
104 The following methods should be called by the :meth:`initialize` method
104 The following methods should be called by the :meth:`initialize` method
105 of the subclass:
105 of the subclass:
106
106
107 - :meth:`init_path`
107 - :meth:`init_path`
108 - :meth:`init_shell` (to be implemented by the subclass)
108 - :meth:`init_shell` (to be implemented by the subclass)
109 - :meth:`init_gui_pylab`
109 - :meth:`init_gui_pylab`
110 - :meth:`init_extensions`
110 - :meth:`init_extensions`
111 - :meth:`init_code`
111 - :meth:`init_code`
112 """
112 """
113 extensions = List(Unicode(),
113 extensions = List(Unicode(),
114 help="A list of dotted module names of IPython extensions to load."
114 help="A list of dotted module names of IPython extensions to load."
115 ).tag(config=True)
115 ).tag(config=True)
116 extra_extension = Unicode('',
116 extra_extension = Unicode('',
117 help="dotted module name of an IPython extension to load."
117 help="dotted module name of an IPython extension to load."
118 ).tag(config=True)
118 ).tag(config=True)
119
119
120 reraise_ipython_extension_failures = Bool(False,
120 reraise_ipython_extension_failures = Bool(False,
121 help="Reraise exceptions encountered loading IPython extensions?",
121 help="Reraise exceptions encountered loading IPython extensions?",
122 ).tag(config=True)
122 ).tag(config=True)
123
123
124 # Extensions that are always loaded (not configurable)
124 # Extensions that are always loaded (not configurable)
125 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
125 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
126
126
127 hide_initial_ns = Bool(True,
127 hide_initial_ns = Bool(True,
128 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
128 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
129 be hidden from tools like %who?"""
129 be hidden from tools like %who?"""
130 ).tag(config=True)
130 ).tag(config=True)
131
131
132 exec_files = List(Unicode(),
132 exec_files = List(Unicode(),
133 help="""List of files to run at IPython startup."""
133 help="""List of files to run at IPython startup."""
134 ).tag(config=True)
134 ).tag(config=True)
135 exec_PYTHONSTARTUP = Bool(True,
135 exec_PYTHONSTARTUP = Bool(True,
136 help="""Run the file referenced by the PYTHONSTARTUP environment
136 help="""Run the file referenced by the PYTHONSTARTUP environment
137 variable at IPython startup."""
137 variable at IPython startup."""
138 ).tag(config=True)
138 ).tag(config=True)
139 file_to_run = Unicode('',
139 file_to_run = Unicode('',
140 help="""A file to be run""").tag(config=True)
140 help="""A file to be run""").tag(config=True)
141
141
142 exec_lines = List(Unicode(),
142 exec_lines = List(Unicode(),
143 help="""lines of code to run at IPython startup."""
143 help="""lines of code to run at IPython startup."""
144 ).tag(config=True)
144 ).tag(config=True)
145 code_to_run = Unicode('',
145 code_to_run = Unicode('',
146 help="Execute the given command string."
146 help="Execute the given command string."
147 ).tag(config=True)
147 ).tag(config=True)
148 module_to_run = Unicode('',
148 module_to_run = Unicode('',
149 help="Run the module as a script."
149 help="Run the module as a script."
150 ).tag(config=True)
150 ).tag(config=True)
151 gui = CaselessStrEnum(gui_keys, allow_none=True,
151 gui = CaselessStrEnum(gui_keys, allow_none=True,
152 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
152 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
153 ).tag(config=True)
153 ).tag(config=True)
154 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
154 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
155 help="""Configure matplotlib for interactive use with
155 help="""Configure matplotlib for interactive use with
156 the default matplotlib backend."""
156 the default matplotlib backend."""
157 ).tag(config=True)
157 ).tag(config=True)
158 pylab = CaselessStrEnum(backend_keys, allow_none=True,
158 pylab = CaselessStrEnum(backend_keys, allow_none=True,
159 help="""Pre-load matplotlib and numpy for interactive use,
159 help="""Pre-load matplotlib and numpy for interactive use,
160 selecting a particular matplotlib backend and loop integration.
160 selecting a particular matplotlib backend and loop integration.
161 """
161 """
162 ).tag(config=True)
162 ).tag(config=True)
163 pylab_import_all = Bool(True,
163 pylab_import_all = Bool(True,
164 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
164 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
165 and an ``import *`` is done from numpy and pylab, when using pylab mode.
165 and an ``import *`` is done from numpy and pylab, when using pylab mode.
166
166
167 When False, pylab mode should not import any names into the user namespace.
167 When False, pylab mode should not import any names into the user namespace.
168 """
168 """
169 ).tag(config=True)
169 ).tag(config=True)
170 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
170 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
171 allow_none=True)
171 allow_none=True)
172 # whether interact-loop should start
172 # whether interact-loop should start
173 interact = Bool(True)
173 interact = Bool(True)
174
174
175 user_ns = Instance(dict, args=None, allow_none=True)
175 user_ns = Instance(dict, args=None, allow_none=True)
176 @observe('user_ns')
176 @observe('user_ns')
177 def _user_ns_changed(self, change):
177 def _user_ns_changed(self, change):
178 if self.shell is not None:
178 if self.shell is not None:
179 self.shell.user_ns = change['new']
179 self.shell.user_ns = change['new']
180 self.shell.init_user_ns()
180 self.shell.init_user_ns()
181
181
182 def init_path(self):
182 def init_path(self):
183 """Add current working directory, '', to sys.path"""
183 """Add current working directory, '', to sys.path"""
184 if sys.path[0] != '':
184 if sys.path[0] != '':
185 sys.path.insert(0, '')
185 sys.path.insert(0, '')
186
186
187 def init_shell(self):
187 def init_shell(self):
188 raise NotImplementedError("Override in subclasses")
188 raise NotImplementedError("Override in subclasses")
189
189
190 def init_gui_pylab(self):
190 def init_gui_pylab(self):
191 """Enable GUI event loop integration, taking pylab into account."""
191 """Enable GUI event loop integration, taking pylab into account."""
192 enable = False
192 enable = False
193 shell = self.shell
193 shell = self.shell
194 if self.pylab:
194 if self.pylab:
195 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
195 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
196 key = self.pylab
196 key = self.pylab
197 elif self.matplotlib:
197 elif self.matplotlib:
198 enable = shell.enable_matplotlib
198 enable = shell.enable_matplotlib
199 key = self.matplotlib
199 key = self.matplotlib
200 elif self.gui:
200 elif self.gui:
201 enable = shell.enable_gui
201 enable = shell.enable_gui
202 key = self.gui
202 key = self.gui
203
203
204 if not enable:
204 if not enable:
205 return
205 return
206
206
207 try:
207 try:
208 r = enable(key)
208 r = enable(key)
209 except ImportError:
209 except ImportError:
210 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
210 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
211 self.shell.showtraceback()
211 self.shell.showtraceback()
212 return
212 return
213 except Exception:
213 except Exception:
214 self.log.warning("GUI event loop or pylab initialization failed")
214 self.log.warning("GUI event loop or pylab initialization failed")
215 self.shell.showtraceback()
215 self.shell.showtraceback()
216 return
216 return
217
217
218 if isinstance(r, tuple):
218 if isinstance(r, tuple):
219 gui, backend = r[:2]
219 gui, backend = r[:2]
220 self.log.info("Enabling GUI event loop integration, "
220 self.log.info("Enabling GUI event loop integration, "
221 "eventloop=%s, matplotlib=%s", gui, backend)
221 "eventloop=%s, matplotlib=%s", gui, backend)
222 if key == "auto":
222 if key == "auto":
223 print("Using matplotlib backend: %s" % backend)
223 print("Using matplotlib backend: %s" % backend)
224 else:
224 else:
225 gui = r
225 gui = r
226 self.log.info("Enabling GUI event loop integration, "
226 self.log.info("Enabling GUI event loop integration, "
227 "eventloop=%s", gui)
227 "eventloop=%s", gui)
228
228
229 def init_extensions(self):
229 def init_extensions(self):
230 """Load all IPython extensions in IPythonApp.extensions.
230 """Load all IPython extensions in IPythonApp.extensions.
231
231
232 This uses the :meth:`ExtensionManager.load_extensions` to load all
232 This uses the :meth:`ExtensionManager.load_extensions` to load all
233 the extensions listed in ``self.extensions``.
233 the extensions listed in ``self.extensions``.
234 """
234 """
235 try:
235 try:
236 self.log.debug("Loading IPython extensions...")
236 self.log.debug("Loading IPython extensions...")
237 extensions = self.default_extensions + self.extensions
237 extensions = self.default_extensions + self.extensions
238 if self.extra_extension:
238 if self.extra_extension:
239 extensions.append(self.extra_extension)
239 extensions.append(self.extra_extension)
240 for ext in extensions:
240 for ext in extensions:
241 try:
241 try:
242 self.log.info("Loading IPython extension: %s" % ext)
242 self.log.info("Loading IPython extension: %s" % ext)
243 self.shell.extension_manager.load_extension(ext)
243 self.shell.extension_manager.load_extension(ext)
244 except:
244 except:
245 if self.reraise_ipython_extension_failures:
245 if self.reraise_ipython_extension_failures:
246 raise
246 raise
247 msg = ("Error in loading extension: {ext}\n"
247 msg = ("Error in loading extension: {ext}\n"
248 "Check your config files in {location}".format(
248 "Check your config files in {location}".format(
249 ext=ext,
249 ext=ext,
250 location=self.profile_dir.location
250 location=self.profile_dir.location
251 ))
251 ))
252 self.log.warning(msg, exc_info=True)
252 self.log.warning(msg, exc_info=True)
253 except:
253 except:
254 if self.reraise_ipython_extension_failures:
254 if self.reraise_ipython_extension_failures:
255 raise
255 raise
256 self.log.warning("Unknown error in loading extensions:", exc_info=True)
256 self.log.warning("Unknown error in loading extensions:", exc_info=True)
257
257
258 def init_code(self):
258 def init_code(self):
259 """run the pre-flight code, specified via exec_lines"""
259 """run the pre-flight code, specified via exec_lines"""
260 self._run_startup_files()
260 self._run_startup_files()
261 self._run_exec_lines()
261 self._run_exec_lines()
262 self._run_exec_files()
262 self._run_exec_files()
263
263
264 # Hide variables defined here from %who etc.
264 # Hide variables defined here from %who etc.
265 if self.hide_initial_ns:
265 if self.hide_initial_ns:
266 self.shell.user_ns_hidden.update(self.shell.user_ns)
266 self.shell.user_ns_hidden.update(self.shell.user_ns)
267
267
268 # command-line execution (ipython -i script.py, ipython -m module)
268 # command-line execution (ipython -i script.py, ipython -m module)
269 # should *not* be excluded from %whos
269 # should *not* be excluded from %whos
270 self._run_cmd_line_code()
270 self._run_cmd_line_code()
271 self._run_module()
271 self._run_module()
272
272
273 # flush output, so itwon't be attached to the first cell
273 # flush output, so itwon't be attached to the first cell
274 sys.stdout.flush()
274 sys.stdout.flush()
275 sys.stderr.flush()
275 sys.stderr.flush()
276
276
277 def _run_exec_lines(self):
277 def _run_exec_lines(self):
278 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
278 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
279 if not self.exec_lines:
279 if not self.exec_lines:
280 return
280 return
281 try:
281 try:
282 self.log.debug("Running code from IPythonApp.exec_lines...")
282 self.log.debug("Running code from IPythonApp.exec_lines...")
283 for line in self.exec_lines:
283 for line in self.exec_lines:
284 try:
284 try:
285 self.log.info("Running code in user namespace: %s" %
285 self.log.info("Running code in user namespace: %s" %
286 line)
286 line)
287 self.shell.run_cell(line, store_history=False)
287 self.shell.run_cell(line, store_history=False)
288 except:
288 except:
289 self.log.warning("Error in executing line in user "
289 self.log.warning("Error in executing line in user "
290 "namespace: %s" % line)
290 "namespace: %s" % line)
291 self.shell.showtraceback()
291 self.shell.showtraceback()
292 except:
292 except:
293 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
293 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
294 self.shell.showtraceback()
294 self.shell.showtraceback()
295
295
296 def _exec_file(self, fname, shell_futures=False):
296 def _exec_file(self, fname, shell_futures=False):
297 try:
297 try:
298 full_filename = filefind(fname, [u'.', self.ipython_dir])
298 full_filename = filefind(fname, [u'.', self.ipython_dir])
299 except IOError:
299 except IOError:
300 self.log.warning("File not found: %r"%fname)
300 self.log.warning("File not found: %r"%fname)
301 return
301 return
302 # Make sure that the running script gets a proper sys.argv as if it
302 # Make sure that the running script gets a proper sys.argv as if it
303 # were run from a system shell.
303 # were run from a system shell.
304 save_argv = sys.argv
304 save_argv = sys.argv
305 sys.argv = [full_filename] + self.extra_args[1:]
305 sys.argv = [full_filename] + self.extra_args[1:]
306 # protect sys.argv from potential unicode strings on Python 2:
307 if not py3compat.PY3:
308 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
309 try:
306 try:
310 if os.path.isfile(full_filename):
307 if os.path.isfile(full_filename):
311 self.log.info("Running file in user namespace: %s" %
308 self.log.info("Running file in user namespace: %s" %
312 full_filename)
309 full_filename)
313 # Ensure that __file__ is always defined to match Python
310 # Ensure that __file__ is always defined to match Python
314 # behavior.
311 # behavior.
315 with preserve_keys(self.shell.user_ns, '__file__'):
312 with preserve_keys(self.shell.user_ns, '__file__'):
316 self.shell.user_ns['__file__'] = fname
313 self.shell.user_ns['__file__'] = fname
317 if full_filename.endswith('.ipy'):
314 if full_filename.endswith('.ipy'):
318 self.shell.safe_execfile_ipy(full_filename,
315 self.shell.safe_execfile_ipy(full_filename,
319 shell_futures=shell_futures)
316 shell_futures=shell_futures)
320 else:
317 else:
321 # default to python, even without extension
318 # default to python, even without extension
322 self.shell.safe_execfile(full_filename,
319 self.shell.safe_execfile(full_filename,
323 self.shell.user_ns,
320 self.shell.user_ns,
324 shell_futures=shell_futures,
321 shell_futures=shell_futures,
325 raise_exceptions=True)
322 raise_exceptions=True)
326 finally:
323 finally:
327 sys.argv = save_argv
324 sys.argv = save_argv
328
325
329 def _run_startup_files(self):
326 def _run_startup_files(self):
330 """Run files from profile startup directory"""
327 """Run files from profile startup directory"""
331 startup_dir = self.profile_dir.startup_dir
328 startup_dir = self.profile_dir.startup_dir
332 startup_files = []
329 startup_files = []
333
330
334 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
331 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
335 not (self.file_to_run or self.code_to_run or self.module_to_run):
332 not (self.file_to_run or self.code_to_run or self.module_to_run):
336 python_startup = os.environ['PYTHONSTARTUP']
333 python_startup = os.environ['PYTHONSTARTUP']
337 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
334 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
338 try:
335 try:
339 self._exec_file(python_startup)
336 self._exec_file(python_startup)
340 except:
337 except:
341 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
338 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
342 self.shell.showtraceback()
339 self.shell.showtraceback()
343
340
344 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
341 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
345 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
342 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
346 if not startup_files:
343 if not startup_files:
347 return
344 return
348
345
349 self.log.debug("Running startup files from %s...", startup_dir)
346 self.log.debug("Running startup files from %s...", startup_dir)
350 try:
347 try:
351 for fname in sorted(startup_files):
348 for fname in sorted(startup_files):
352 self._exec_file(fname)
349 self._exec_file(fname)
353 except:
350 except:
354 self.log.warning("Unknown error in handling startup files:")
351 self.log.warning("Unknown error in handling startup files:")
355 self.shell.showtraceback()
352 self.shell.showtraceback()
356
353
357 def _run_exec_files(self):
354 def _run_exec_files(self):
358 """Run files from IPythonApp.exec_files"""
355 """Run files from IPythonApp.exec_files"""
359 if not self.exec_files:
356 if not self.exec_files:
360 return
357 return
361
358
362 self.log.debug("Running files in IPythonApp.exec_files...")
359 self.log.debug("Running files in IPythonApp.exec_files...")
363 try:
360 try:
364 for fname in self.exec_files:
361 for fname in self.exec_files:
365 self._exec_file(fname)
362 self._exec_file(fname)
366 except:
363 except:
367 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
364 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
368 self.shell.showtraceback()
365 self.shell.showtraceback()
369
366
370 def _run_cmd_line_code(self):
367 def _run_cmd_line_code(self):
371 """Run code or file specified at the command-line"""
368 """Run code or file specified at the command-line"""
372 if self.code_to_run:
369 if self.code_to_run:
373 line = self.code_to_run
370 line = self.code_to_run
374 try:
371 try:
375 self.log.info("Running code given at command line (c=): %s" %
372 self.log.info("Running code given at command line (c=): %s" %
376 line)
373 line)
377 self.shell.run_cell(line, store_history=False)
374 self.shell.run_cell(line, store_history=False)
378 except:
375 except:
379 self.log.warning("Error in executing line in user namespace: %s" %
376 self.log.warning("Error in executing line in user namespace: %s" %
380 line)
377 line)
381 self.shell.showtraceback()
378 self.shell.showtraceback()
382 if not self.interact:
379 if not self.interact:
383 self.exit(1)
380 self.exit(1)
384
381
385 # Like Python itself, ignore the second if the first of these is present
382 # Like Python itself, ignore the second if the first of these is present
386 elif self.file_to_run:
383 elif self.file_to_run:
387 fname = self.file_to_run
384 fname = self.file_to_run
388 if os.path.isdir(fname):
385 if os.path.isdir(fname):
389 fname = os.path.join(fname, "__main__.py")
386 fname = os.path.join(fname, "__main__.py")
390 try:
387 try:
391 self._exec_file(fname, shell_futures=True)
388 self._exec_file(fname, shell_futures=True)
392 except:
389 except:
393 self.shell.showtraceback(tb_offset=4)
390 self.shell.showtraceback(tb_offset=4)
394 if not self.interact:
391 if not self.interact:
395 self.exit(1)
392 self.exit(1)
396
393
397 def _run_module(self):
394 def _run_module(self):
398 """Run module specified at the command-line."""
395 """Run module specified at the command-line."""
399 if self.module_to_run:
396 if self.module_to_run:
400 # Make sure that the module gets a proper sys.argv as if it were
397 # Make sure that the module gets a proper sys.argv as if it were
401 # run using `python -m`.
398 # run using `python -m`.
402 save_argv = sys.argv
399 save_argv = sys.argv
403 sys.argv = [sys.executable] + self.extra_args
400 sys.argv = [sys.executable] + self.extra_args
404 try:
401 try:
405 self.shell.safe_run_module(self.module_to_run,
402 self.shell.safe_run_module(self.module_to_run,
406 self.shell.user_ns)
403 self.shell.user_ns)
407 finally:
404 finally:
408 sys.argv = save_argv
405 sys.argv = save_argv
@@ -1,42 +1,39 b''
1 # coding: utf-8
1 # coding: utf-8
2 import nose.tools as nt
2 import nose.tools as nt
3
3
4 from IPython.core.splitinput import split_user_input, LineInfo
4 from IPython.core.splitinput import split_user_input, LineInfo
5 from IPython.testing import tools as tt
5 from IPython.testing import tools as tt
6 from IPython.utils import py3compat
6 from IPython.utils import py3compat
7
7
8 tests = [
8 tests = [
9 ('x=1', ('', '', 'x', '=1')),
9 ('x=1', ('', '', 'x', '=1')),
10 ('?', ('', '?', '', '')),
10 ('?', ('', '?', '', '')),
11 ('??', ('', '??', '', '')),
11 ('??', ('', '??', '', '')),
12 (' ?', (' ', '?', '', '')),
12 (' ?', (' ', '?', '', '')),
13 (' ??', (' ', '??', '', '')),
13 (' ??', (' ', '??', '', '')),
14 ('??x', ('', '??', 'x', '')),
14 ('??x', ('', '??', 'x', '')),
15 ('?x=1', ('', '?', 'x', '=1')),
15 ('?x=1', ('', '?', 'x', '=1')),
16 ('!ls', ('', '!', 'ls', '')),
16 ('!ls', ('', '!', 'ls', '')),
17 (' !ls', (' ', '!', 'ls', '')),
17 (' !ls', (' ', '!', 'ls', '')),
18 ('!!ls', ('', '!!', 'ls', '')),
18 ('!!ls', ('', '!!', 'ls', '')),
19 (' !!ls', (' ', '!!', 'ls', '')),
19 (' !!ls', (' ', '!!', 'ls', '')),
20 (',ls', ('', ',', 'ls', '')),
20 (',ls', ('', ',', 'ls', '')),
21 (';ls', ('', ';', 'ls', '')),
21 (';ls', ('', ';', 'ls', '')),
22 (' ;ls', (' ', ';', 'ls', '')),
22 (' ;ls', (' ', ';', 'ls', '')),
23 ('f.g(x)', ('', '', 'f.g', '(x)')),
23 ('f.g(x)', ('', '', 'f.g', '(x)')),
24 ('f.g (x)', ('', '', 'f.g', '(x)')),
24 ('f.g (x)', ('', '', 'f.g', '(x)')),
25 ('?%hist1', ('', '?', '%hist1', '')),
25 ('?%hist1', ('', '?', '%hist1', '')),
26 ('?%%hist2', ('', '?', '%%hist2', '')),
26 ('?%%hist2', ('', '?', '%%hist2', '')),
27 ('??%hist3', ('', '??', '%hist3', '')),
27 ('??%hist3', ('', '??', '%hist3', '')),
28 ('??%%hist4', ('', '??', '%%hist4', '')),
28 ('??%%hist4', ('', '??', '%%hist4', '')),
29 ('?x*', ('', '?', 'x*', '')),
29 ('?x*', ('', '?', 'x*', '')),
30 ]
30 ]
31 if py3compat.PY3:
32 tests.append((u"PΓ©rez Fernando", (u'', u'', u'PΓ©rez', u'Fernando')))
31 tests.append((u"PΓ©rez Fernando", (u'', u'', u'PΓ©rez', u'Fernando')))
33 else:
34 tests.append((u"PΓ©rez Fernando", (u'', u'', u'P', u'Γ©rez Fernando')))
35
32
36 def test_split_user_input():
33 def test_split_user_input():
37 return tt.check_pairs(split_user_input, tests)
34 return tt.check_pairs(split_user_input, tests)
38
35
39 def test_LineInfo():
36 def test_LineInfo():
40 """Simple test for LineInfo construction and str()"""
37 """Simple test for LineInfo construction and str()"""
41 linfo = LineInfo(' %cd /home')
38 linfo = LineInfo(' %cd /home')
42 nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]')
39 nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]')
@@ -1,1468 +1,1461 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Verbose and colourful traceback formatting.
3 Verbose and colourful traceback formatting.
4
4
5 **ColorTB**
5 **ColorTB**
6
6
7 I've always found it a bit hard to visually parse tracebacks in Python. The
7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 ColorTB class is a solution to that problem. It colors the different parts of a
8 ColorTB class is a solution to that problem. It colors the different parts of a
9 traceback in a manner similar to what you would expect from a syntax-highlighting
9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 text editor.
10 text editor.
11
11
12 Installation instructions for ColorTB::
12 Installation instructions for ColorTB::
13
13
14 import sys,ultratb
14 import sys,ultratb
15 sys.excepthook = ultratb.ColorTB()
15 sys.excepthook = ultratb.ColorTB()
16
16
17 **VerboseTB**
17 **VerboseTB**
18
18
19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 of useful info when a traceback occurs. Ping originally had it spit out HTML
20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 and intended it for CGI programmers, but why should they have all the fun? I
21 and intended it for CGI programmers, but why should they have all the fun? I
22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 but kind of neat, and maybe useful for long-running programs that you believe
23 but kind of neat, and maybe useful for long-running programs that you believe
24 are bug-free. If a crash *does* occur in that type of program you want details.
24 are bug-free. If a crash *does* occur in that type of program you want details.
25 Give it a shot--you'll love it or you'll hate it.
25 Give it a shot--you'll love it or you'll hate it.
26
26
27 .. note::
27 .. note::
28
28
29 The Verbose mode prints the variables currently visible where the exception
29 The Verbose mode prints the variables currently visible where the exception
30 happened (shortening their strings if too long). This can potentially be
30 happened (shortening their strings if too long). This can potentially be
31 very slow, if you happen to have a huge data structure whose string
31 very slow, if you happen to have a huge data structure whose string
32 representation is complex to compute. Your computer may appear to freeze for
32 representation is complex to compute. Your computer may appear to freeze for
33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 with Ctrl-C (maybe hitting it more than once).
34 with Ctrl-C (maybe hitting it more than once).
35
35
36 If you encounter this kind of situation often, you may want to use the
36 If you encounter this kind of situation often, you may want to use the
37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 variables (but otherwise includes the information and context given by
38 variables (but otherwise includes the information and context given by
39 Verbose).
39 Verbose).
40
40
41 .. note::
41 .. note::
42
42
43 The verbose mode print all variables in the stack, which means it can
43 The verbose mode print all variables in the stack, which means it can
44 potentially leak sensitive information like access keys, or unencryted
44 potentially leak sensitive information like access keys, or unencryted
45 password.
45 password.
46
46
47 Installation instructions for VerboseTB::
47 Installation instructions for VerboseTB::
48
48
49 import sys,ultratb
49 import sys,ultratb
50 sys.excepthook = ultratb.VerboseTB()
50 sys.excepthook = ultratb.VerboseTB()
51
51
52 Note: Much of the code in this module was lifted verbatim from the standard
52 Note: Much of the code in this module was lifted verbatim from the standard
53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54
54
55 Color schemes
55 Color schemes
56 -------------
56 -------------
57
57
58 The colors are defined in the class TBTools through the use of the
58 The colors are defined in the class TBTools through the use of the
59 ColorSchemeTable class. Currently the following exist:
59 ColorSchemeTable class. Currently the following exist:
60
60
61 - NoColor: allows all of this module to be used in any terminal (the color
61 - NoColor: allows all of this module to be used in any terminal (the color
62 escapes are just dummy blank strings).
62 escapes are just dummy blank strings).
63
63
64 - Linux: is meant to look good in a terminal like the Linux console (black
64 - Linux: is meant to look good in a terminal like the Linux console (black
65 or very dark background).
65 or very dark background).
66
66
67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 in light background terminals.
68 in light background terminals.
69
69
70 - Neutral: a neutral color scheme that should be readable on both light and
70 - Neutral: a neutral color scheme that should be readable on both light and
71 dark background
71 dark background
72
72
73 You can implement other color schemes easily, the syntax is fairly
73 You can implement other color schemes easily, the syntax is fairly
74 self-explanatory. Please send back new schemes you develop to the author for
74 self-explanatory. Please send back new schemes you develop to the author for
75 possible inclusion in future releases.
75 possible inclusion in future releases.
76
76
77 Inheritance diagram:
77 Inheritance diagram:
78
78
79 .. inheritance-diagram:: IPython.core.ultratb
79 .. inheritance-diagram:: IPython.core.ultratb
80 :parts: 3
80 :parts: 3
81 """
81 """
82
82
83 #*****************************************************************************
83 #*****************************************************************************
84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 #
86 #
87 # Distributed under the terms of the BSD License. The full license is in
87 # Distributed under the terms of the BSD License. The full license is in
88 # the file COPYING, distributed as part of this software.
88 # the file COPYING, distributed as part of this software.
89 #*****************************************************************************
89 #*****************************************************************************
90
90
91
91
92 import dis
92 import dis
93 import inspect
93 import inspect
94 import keyword
94 import keyword
95 import linecache
95 import linecache
96 import os
96 import os
97 import pydoc
97 import pydoc
98 import re
98 import re
99 import sys
99 import sys
100 import time
100 import time
101 import tokenize
101 import tokenize
102 import traceback
102 import traceback
103 import types
103 import types
104
104
105 try: # Python 2
105 try: # Python 2
106 generate_tokens = tokenize.generate_tokens
106 generate_tokens = tokenize.generate_tokens
107 except AttributeError: # Python 3
107 except AttributeError: # Python 3
108 generate_tokens = tokenize.tokenize
108 generate_tokens = tokenize.tokenize
109
109
110 # For purposes of monkeypatching inspect to fix a bug in it.
110 # For purposes of monkeypatching inspect to fix a bug in it.
111 from inspect import getsourcefile, getfile, getmodule, \
111 from inspect import getsourcefile, getfile, getmodule, \
112 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
112 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
113
113
114 # IPython's own modules
114 # IPython's own modules
115 from IPython import get_ipython
115 from IPython import get_ipython
116 from IPython.core import debugger
116 from IPython.core import debugger
117 from IPython.core.display_trap import DisplayTrap
117 from IPython.core.display_trap import DisplayTrap
118 from IPython.core.excolors import exception_colors
118 from IPython.core.excolors import exception_colors
119 from IPython.utils import PyColorize
119 from IPython.utils import PyColorize
120 from IPython.utils import openpy
120 from IPython.utils import openpy
121 from IPython.utils import path as util_path
121 from IPython.utils import path as util_path
122 from IPython.utils import py3compat
122 from IPython.utils import py3compat
123 from IPython.utils.data import uniq_stable
123 from IPython.utils.data import uniq_stable
124 from IPython.utils.terminal import get_terminal_size
124 from IPython.utils.terminal import get_terminal_size
125 from logging import info, error
125 from logging import info, error
126
126
127 import IPython.utils.colorable as colorable
127 import IPython.utils.colorable as colorable
128
128
129 # Globals
129 # Globals
130 # amount of space to put line numbers before verbose tracebacks
130 # amount of space to put line numbers before verbose tracebacks
131 INDENT_SIZE = 8
131 INDENT_SIZE = 8
132
132
133 # Default color scheme. This is used, for example, by the traceback
133 # Default color scheme. This is used, for example, by the traceback
134 # formatter. When running in an actual IPython instance, the user's rc.colors
134 # formatter. When running in an actual IPython instance, the user's rc.colors
135 # value is used, but having a module global makes this functionality available
135 # value is used, but having a module global makes this functionality available
136 # to users of ultratb who are NOT running inside ipython.
136 # to users of ultratb who are NOT running inside ipython.
137 DEFAULT_SCHEME = 'NoColor'
137 DEFAULT_SCHEME = 'NoColor'
138
138
139 # ---------------------------------------------------------------------------
139 # ---------------------------------------------------------------------------
140 # Code begins
140 # Code begins
141
141
142 # Utility functions
142 # Utility functions
143 def inspect_error():
143 def inspect_error():
144 """Print a message about internal inspect errors.
144 """Print a message about internal inspect errors.
145
145
146 These are unfortunately quite common."""
146 These are unfortunately quite common."""
147
147
148 error('Internal Python error in the inspect module.\n'
148 error('Internal Python error in the inspect module.\n'
149 'Below is the traceback from this internal error.\n')
149 'Below is the traceback from this internal error.\n')
150
150
151
151
152 # This function is a monkeypatch we apply to the Python inspect module. We have
152 # This function is a monkeypatch we apply to the Python inspect module. We have
153 # now found when it's needed (see discussion on issue gh-1456), and we have a
153 # now found when it's needed (see discussion on issue gh-1456), and we have a
154 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
154 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
155 # the monkeypatch is not applied. TK, Aug 2012.
155 # the monkeypatch is not applied. TK, Aug 2012.
156 def findsource(object):
156 def findsource(object):
157 """Return the entire source file and starting line number for an object.
157 """Return the entire source file and starting line number for an object.
158
158
159 The argument may be a module, class, method, function, traceback, frame,
159 The argument may be a module, class, method, function, traceback, frame,
160 or code object. The source code is returned as a list of all the lines
160 or code object. The source code is returned as a list of all the lines
161 in the file and the line number indexes a line in that list. An IOError
161 in the file and the line number indexes a line in that list. An IOError
162 is raised if the source code cannot be retrieved.
162 is raised if the source code cannot be retrieved.
163
163
164 FIXED version with which we monkeypatch the stdlib to work around a bug."""
164 FIXED version with which we monkeypatch the stdlib to work around a bug."""
165
165
166 file = getsourcefile(object) or getfile(object)
166 file = getsourcefile(object) or getfile(object)
167 # If the object is a frame, then trying to get the globals dict from its
167 # If the object is a frame, then trying to get the globals dict from its
168 # module won't work. Instead, the frame object itself has the globals
168 # module won't work. Instead, the frame object itself has the globals
169 # dictionary.
169 # dictionary.
170 globals_dict = None
170 globals_dict = None
171 if inspect.isframe(object):
171 if inspect.isframe(object):
172 # XXX: can this ever be false?
172 # XXX: can this ever be false?
173 globals_dict = object.f_globals
173 globals_dict = object.f_globals
174 else:
174 else:
175 module = getmodule(object, file)
175 module = getmodule(object, file)
176 if module:
176 if module:
177 globals_dict = module.__dict__
177 globals_dict = module.__dict__
178 lines = linecache.getlines(file, globals_dict)
178 lines = linecache.getlines(file, globals_dict)
179 if not lines:
179 if not lines:
180 raise IOError('could not get source code')
180 raise IOError('could not get source code')
181
181
182 if ismodule(object):
182 if ismodule(object):
183 return lines, 0
183 return lines, 0
184
184
185 if isclass(object):
185 if isclass(object):
186 name = object.__name__
186 name = object.__name__
187 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
187 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
188 # make some effort to find the best matching class definition:
188 # make some effort to find the best matching class definition:
189 # use the one with the least indentation, which is the one
189 # use the one with the least indentation, which is the one
190 # that's most probably not inside a function definition.
190 # that's most probably not inside a function definition.
191 candidates = []
191 candidates = []
192 for i in range(len(lines)):
192 for i in range(len(lines)):
193 match = pat.match(lines[i])
193 match = pat.match(lines[i])
194 if match:
194 if match:
195 # if it's at toplevel, it's already the best one
195 # if it's at toplevel, it's already the best one
196 if lines[i][0] == 'c':
196 if lines[i][0] == 'c':
197 return lines, i
197 return lines, i
198 # else add whitespace to candidate list
198 # else add whitespace to candidate list
199 candidates.append((match.group(1), i))
199 candidates.append((match.group(1), i))
200 if candidates:
200 if candidates:
201 # this will sort by whitespace, and by line number,
201 # this will sort by whitespace, and by line number,
202 # less whitespace first
202 # less whitespace first
203 candidates.sort()
203 candidates.sort()
204 return lines, candidates[0][1]
204 return lines, candidates[0][1]
205 else:
205 else:
206 raise IOError('could not find class definition')
206 raise IOError('could not find class definition')
207
207
208 if ismethod(object):
208 if ismethod(object):
209 object = object.__func__
209 object = object.__func__
210 if isfunction(object):
210 if isfunction(object):
211 object = object.__code__
211 object = object.__code__
212 if istraceback(object):
212 if istraceback(object):
213 object = object.tb_frame
213 object = object.tb_frame
214 if isframe(object):
214 if isframe(object):
215 object = object.f_code
215 object = object.f_code
216 if iscode(object):
216 if iscode(object):
217 if not hasattr(object, 'co_firstlineno'):
217 if not hasattr(object, 'co_firstlineno'):
218 raise IOError('could not find function definition')
218 raise IOError('could not find function definition')
219 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
219 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
220 pmatch = pat.match
220 pmatch = pat.match
221 # fperez - fix: sometimes, co_firstlineno can give a number larger than
221 # fperez - fix: sometimes, co_firstlineno can give a number larger than
222 # the length of lines, which causes an error. Safeguard against that.
222 # the length of lines, which causes an error. Safeguard against that.
223 lnum = min(object.co_firstlineno, len(lines)) - 1
223 lnum = min(object.co_firstlineno, len(lines)) - 1
224 while lnum > 0:
224 while lnum > 0:
225 if pmatch(lines[lnum]):
225 if pmatch(lines[lnum]):
226 break
226 break
227 lnum -= 1
227 lnum -= 1
228
228
229 return lines, lnum
229 return lines, lnum
230 raise IOError('could not find code object')
230 raise IOError('could not find code object')
231
231
232
232
233 # This is a patched version of inspect.getargs that applies the (unmerged)
233 # This is a patched version of inspect.getargs that applies the (unmerged)
234 # patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes
234 # patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes
235 # https://github.com/ipython/ipython/issues/8205 and
235 # https://github.com/ipython/ipython/issues/8205 and
236 # https://github.com/ipython/ipython/issues/8293
236 # https://github.com/ipython/ipython/issues/8293
237 def getargs(co):
237 def getargs(co):
238 """Get information about the arguments accepted by a code object.
238 """Get information about the arguments accepted by a code object.
239
239
240 Three things are returned: (args, varargs, varkw), where 'args' is
240 Three things are returned: (args, varargs, varkw), where 'args' is
241 a list of argument names (possibly containing nested lists), and
241 a list of argument names (possibly containing nested lists), and
242 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
242 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
243 if not iscode(co):
243 if not iscode(co):
244 raise TypeError('{!r} is not a code object'.format(co))
244 raise TypeError('{!r} is not a code object'.format(co))
245
245
246 nargs = co.co_argcount
246 nargs = co.co_argcount
247 names = co.co_varnames
247 names = co.co_varnames
248 args = list(names[:nargs])
248 args = list(names[:nargs])
249 step = 0
249 step = 0
250
250
251 # The following acrobatics are for anonymous (tuple) arguments.
251 # The following acrobatics are for anonymous (tuple) arguments.
252 for i in range(nargs):
252 for i in range(nargs):
253 if args[i][:1] in ('', '.'):
253 if args[i][:1] in ('', '.'):
254 stack, remain, count = [], [], []
254 stack, remain, count = [], [], []
255 while step < len(co.co_code):
255 while step < len(co.co_code):
256 op = ord(co.co_code[step])
256 op = ord(co.co_code[step])
257 step = step + 1
257 step = step + 1
258 if op >= dis.HAVE_ARGUMENT:
258 if op >= dis.HAVE_ARGUMENT:
259 opname = dis.opname[op]
259 opname = dis.opname[op]
260 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
260 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
261 step = step + 2
261 step = step + 2
262 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
262 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
263 remain.append(value)
263 remain.append(value)
264 count.append(value)
264 count.append(value)
265 elif opname in ('STORE_FAST', 'STORE_DEREF'):
265 elif opname in ('STORE_FAST', 'STORE_DEREF'):
266 if op in dis.haslocal:
266 if op in dis.haslocal:
267 stack.append(co.co_varnames[value])
267 stack.append(co.co_varnames[value])
268 elif op in dis.hasfree:
268 elif op in dis.hasfree:
269 stack.append((co.co_cellvars + co.co_freevars)[value])
269 stack.append((co.co_cellvars + co.co_freevars)[value])
270 # Special case for sublists of length 1: def foo((bar))
270 # Special case for sublists of length 1: def foo((bar))
271 # doesn't generate the UNPACK_TUPLE bytecode, so if
271 # doesn't generate the UNPACK_TUPLE bytecode, so if
272 # `remain` is empty here, we have such a sublist.
272 # `remain` is empty here, we have such a sublist.
273 if not remain:
273 if not remain:
274 stack[0] = [stack[0]]
274 stack[0] = [stack[0]]
275 break
275 break
276 else:
276 else:
277 remain[-1] = remain[-1] - 1
277 remain[-1] = remain[-1] - 1
278 while remain[-1] == 0:
278 while remain[-1] == 0:
279 remain.pop()
279 remain.pop()
280 size = count.pop()
280 size = count.pop()
281 stack[-size:] = [stack[-size:]]
281 stack[-size:] = [stack[-size:]]
282 if not remain:
282 if not remain:
283 break
283 break
284 remain[-1] = remain[-1] - 1
284 remain[-1] = remain[-1] - 1
285 if not remain:
285 if not remain:
286 break
286 break
287 args[i] = stack[0]
287 args[i] = stack[0]
288
288
289 varargs = None
289 varargs = None
290 if co.co_flags & inspect.CO_VARARGS:
290 if co.co_flags & inspect.CO_VARARGS:
291 varargs = co.co_varnames[nargs]
291 varargs = co.co_varnames[nargs]
292 nargs = nargs + 1
292 nargs = nargs + 1
293 varkw = None
293 varkw = None
294 if co.co_flags & inspect.CO_VARKEYWORDS:
294 if co.co_flags & inspect.CO_VARKEYWORDS:
295 varkw = co.co_varnames[nargs]
295 varkw = co.co_varnames[nargs]
296 return inspect.Arguments(args, varargs, varkw)
296 return inspect.Arguments(args, varargs, varkw)
297
297
298
298
299 # Monkeypatch inspect to apply our bugfix.
299 # Monkeypatch inspect to apply our bugfix.
300 def with_patch_inspect(f):
300 def with_patch_inspect(f):
301 """decorator for monkeypatching inspect.findsource"""
301 """
302 Deprecated since IPython 6.0
303 decorator for monkeypatching inspect.findsource
304 """
302
305
303 def wrapped(*args, **kwargs):
306 def wrapped(*args, **kwargs):
304 save_findsource = inspect.findsource
307 save_findsource = inspect.findsource
305 save_getargs = inspect.getargs
308 save_getargs = inspect.getargs
306 inspect.findsource = findsource
309 inspect.findsource = findsource
307 inspect.getargs = getargs
310 inspect.getargs = getargs
308 try:
311 try:
309 return f(*args, **kwargs)
312 return f(*args, **kwargs)
310 finally:
313 finally:
311 inspect.findsource = save_findsource
314 inspect.findsource = save_findsource
312 inspect.getargs = save_getargs
315 inspect.getargs = save_getargs
313
316
314 return wrapped
317 return wrapped
315
318
316
319
317 if py3compat.PY3:
318 fixed_getargvalues = inspect.getargvalues
319 else:
320 # Fixes for https://github.com/ipython/ipython/issues/8293
321 # and https://github.com/ipython/ipython/issues/8205.
322 # The relevant bug is caused by failure to correctly handle anonymous tuple
323 # unpacking, which only exists in Python 2.
324 fixed_getargvalues = with_patch_inspect(inspect.getargvalues)
325
326
327 def fix_frame_records_filenames(records):
320 def fix_frame_records_filenames(records):
328 """Try to fix the filenames in each record from inspect.getinnerframes().
321 """Try to fix the filenames in each record from inspect.getinnerframes().
329
322
330 Particularly, modules loaded from within zip files have useless filenames
323 Particularly, modules loaded from within zip files have useless filenames
331 attached to their code object, and inspect.getinnerframes() just uses it.
324 attached to their code object, and inspect.getinnerframes() just uses it.
332 """
325 """
333 fixed_records = []
326 fixed_records = []
334 for frame, filename, line_no, func_name, lines, index in records:
327 for frame, filename, line_no, func_name, lines, index in records:
335 # Look inside the frame's globals dictionary for __file__,
328 # Look inside the frame's globals dictionary for __file__,
336 # which should be better. However, keep Cython filenames since
329 # which should be better. However, keep Cython filenames since
337 # we prefer the source filenames over the compiled .so file.
330 # we prefer the source filenames over the compiled .so file.
338 filename = py3compat.cast_unicode_py2(filename, "utf-8")
331 filename = py3compat.cast_unicode_py2(filename, "utf-8")
339 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
332 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
340 better_fn = frame.f_globals.get('__file__', None)
333 better_fn = frame.f_globals.get('__file__', None)
341 if isinstance(better_fn, str):
334 if isinstance(better_fn, str):
342 # Check the type just in case someone did something weird with
335 # Check the type just in case someone did something weird with
343 # __file__. It might also be None if the error occurred during
336 # __file__. It might also be None if the error occurred during
344 # import.
337 # import.
345 filename = better_fn
338 filename = better_fn
346 fixed_records.append((frame, filename, line_no, func_name, lines, index))
339 fixed_records.append((frame, filename, line_no, func_name, lines, index))
347 return fixed_records
340 return fixed_records
348
341
349
342
350 @with_patch_inspect
343 @with_patch_inspect
351 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
344 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
352 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
345 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
353
346
354 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
347 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
355 # If the error is at the console, don't build any context, since it would
348 # If the error is at the console, don't build any context, since it would
356 # otherwise produce 5 blank lines printed out (there is no file at the
349 # otherwise produce 5 blank lines printed out (there is no file at the
357 # console)
350 # console)
358 rec_check = records[tb_offset:]
351 rec_check = records[tb_offset:]
359 try:
352 try:
360 rname = rec_check[0][1]
353 rname = rec_check[0][1]
361 if rname == '<ipython console>' or rname.endswith('<string>'):
354 if rname == '<ipython console>' or rname.endswith('<string>'):
362 return rec_check
355 return rec_check
363 except IndexError:
356 except IndexError:
364 pass
357 pass
365
358
366 aux = traceback.extract_tb(etb)
359 aux = traceback.extract_tb(etb)
367 assert len(records) == len(aux)
360 assert len(records) == len(aux)
368 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
361 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
369 maybeStart = lnum - 1 - context // 2
362 maybeStart = lnum - 1 - context // 2
370 start = max(maybeStart, 0)
363 start = max(maybeStart, 0)
371 end = start + context
364 end = start + context
372 lines = linecache.getlines(file)[start:end]
365 lines = linecache.getlines(file)[start:end]
373 buf = list(records[i])
366 buf = list(records[i])
374 buf[LNUM_POS] = lnum
367 buf[LNUM_POS] = lnum
375 buf[INDEX_POS] = lnum - 1 - start
368 buf[INDEX_POS] = lnum - 1 - start
376 buf[LINES_POS] = lines
369 buf[LINES_POS] = lines
377 records[i] = tuple(buf)
370 records[i] = tuple(buf)
378 return records[tb_offset:]
371 return records[tb_offset:]
379
372
380 # Helper function -- largely belongs to VerboseTB, but we need the same
373 # Helper function -- largely belongs to VerboseTB, but we need the same
381 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
374 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
382 # can be recognized properly by ipython.el's py-traceback-line-re
375 # can be recognized properly by ipython.el's py-traceback-line-re
383 # (SyntaxErrors have to be treated specially because they have no traceback)
376 # (SyntaxErrors have to be treated specially because they have no traceback)
384
377
385
378
386 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, _line_format=(lambda x,_:x,None)):
379 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, _line_format=(lambda x,_:x,None)):
387 numbers_width = INDENT_SIZE - 1
380 numbers_width = INDENT_SIZE - 1
388 res = []
381 res = []
389 i = lnum - index
382 i = lnum - index
390
383
391 for line in lines:
384 for line in lines:
392 line = py3compat.cast_unicode(line)
385 line = py3compat.cast_unicode(line)
393
386
394 new_line, err = _line_format(line, 'str')
387 new_line, err = _line_format(line, 'str')
395 if not err: line = new_line
388 if not err: line = new_line
396
389
397 if i == lnum:
390 if i == lnum:
398 # This is the line with the error
391 # This is the line with the error
399 pad = numbers_width - len(str(i))
392 pad = numbers_width - len(str(i))
400 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
393 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
401 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
394 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
402 Colors.line, line, Colors.Normal)
395 Colors.line, line, Colors.Normal)
403 else:
396 else:
404 num = '%*s' % (numbers_width, i)
397 num = '%*s' % (numbers_width, i)
405 line = '%s%s%s %s' % (Colors.lineno, num,
398 line = '%s%s%s %s' % (Colors.lineno, num,
406 Colors.Normal, line)
399 Colors.Normal, line)
407
400
408 res.append(line)
401 res.append(line)
409 if lvals and i == lnum:
402 if lvals and i == lnum:
410 res.append(lvals + '\n')
403 res.append(lvals + '\n')
411 i = i + 1
404 i = i + 1
412 return res
405 return res
413
406
414 def is_recursion_error(etype, value, records):
407 def is_recursion_error(etype, value, records):
415 try:
408 try:
416 # RecursionError is new in Python 3.5
409 # RecursionError is new in Python 3.5
417 recursion_error_type = RecursionError
410 recursion_error_type = RecursionError
418 except NameError:
411 except NameError:
419 recursion_error_type = RuntimeError
412 recursion_error_type = RuntimeError
420
413
421 # The default recursion limit is 1000, but some of that will be taken up
414 # The default recursion limit is 1000, but some of that will be taken up
422 # by stack frames in IPython itself. >500 frames probably indicates
415 # by stack frames in IPython itself. >500 frames probably indicates
423 # a recursion error.
416 # a recursion error.
424 return (etype is recursion_error_type) \
417 return (etype is recursion_error_type) \
425 and "recursion" in str(value).lower() \
418 and "recursion" in str(value).lower() \
426 and len(records) > 500
419 and len(records) > 500
427
420
428 def find_recursion(etype, value, records):
421 def find_recursion(etype, value, records):
429 """Identify the repeating stack frames from a RecursionError traceback
422 """Identify the repeating stack frames from a RecursionError traceback
430
423
431 'records' is a list as returned by VerboseTB.get_records()
424 'records' is a list as returned by VerboseTB.get_records()
432
425
433 Returns (last_unique, repeat_length)
426 Returns (last_unique, repeat_length)
434 """
427 """
435 # This involves a bit of guesswork - we want to show enough of the traceback
428 # This involves a bit of guesswork - we want to show enough of the traceback
436 # to indicate where the recursion is occurring. We guess that the innermost
429 # to indicate where the recursion is occurring. We guess that the innermost
437 # quarter of the traceback (250 frames by default) is repeats, and find the
430 # quarter of the traceback (250 frames by default) is repeats, and find the
438 # first frame (from in to out) that looks different.
431 # first frame (from in to out) that looks different.
439 if not is_recursion_error(etype, value, records):
432 if not is_recursion_error(etype, value, records):
440 return len(records), 0
433 return len(records), 0
441
434
442 # Select filename, lineno, func_name to track frames with
435 # Select filename, lineno, func_name to track frames with
443 records = [r[1:4] for r in records]
436 records = [r[1:4] for r in records]
444 inner_frames = records[-(len(records)//4):]
437 inner_frames = records[-(len(records)//4):]
445 frames_repeated = set(inner_frames)
438 frames_repeated = set(inner_frames)
446
439
447 last_seen_at = {}
440 last_seen_at = {}
448 longest_repeat = 0
441 longest_repeat = 0
449 i = len(records)
442 i = len(records)
450 for frame in reversed(records):
443 for frame in reversed(records):
451 i -= 1
444 i -= 1
452 if frame not in frames_repeated:
445 if frame not in frames_repeated:
453 last_unique = i
446 last_unique = i
454 break
447 break
455
448
456 if frame in last_seen_at:
449 if frame in last_seen_at:
457 distance = last_seen_at[frame] - i
450 distance = last_seen_at[frame] - i
458 longest_repeat = max(longest_repeat, distance)
451 longest_repeat = max(longest_repeat, distance)
459
452
460 last_seen_at[frame] = i
453 last_seen_at[frame] = i
461 else:
454 else:
462 last_unique = 0 # The whole traceback was recursion
455 last_unique = 0 # The whole traceback was recursion
463
456
464 return last_unique, longest_repeat
457 return last_unique, longest_repeat
465
458
466 #---------------------------------------------------------------------------
459 #---------------------------------------------------------------------------
467 # Module classes
460 # Module classes
468 class TBTools(colorable.Colorable):
461 class TBTools(colorable.Colorable):
469 """Basic tools used by all traceback printer classes."""
462 """Basic tools used by all traceback printer classes."""
470
463
471 # Number of frames to skip when reporting tracebacks
464 # Number of frames to skip when reporting tracebacks
472 tb_offset = 0
465 tb_offset = 0
473
466
474 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
467 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
475 # Whether to call the interactive pdb debugger after printing
468 # Whether to call the interactive pdb debugger after printing
476 # tracebacks or not
469 # tracebacks or not
477 super(TBTools, self).__init__(parent=parent, config=config)
470 super(TBTools, self).__init__(parent=parent, config=config)
478 self.call_pdb = call_pdb
471 self.call_pdb = call_pdb
479
472
480 # Output stream to write to. Note that we store the original value in
473 # Output stream to write to. Note that we store the original value in
481 # a private attribute and then make the public ostream a property, so
474 # a private attribute and then make the public ostream a property, so
482 # that we can delay accessing sys.stdout until runtime. The way
475 # that we can delay accessing sys.stdout until runtime. The way
483 # things are written now, the sys.stdout object is dynamically managed
476 # things are written now, the sys.stdout object is dynamically managed
484 # so a reference to it should NEVER be stored statically. This
477 # so a reference to it should NEVER be stored statically. This
485 # property approach confines this detail to a single location, and all
478 # property approach confines this detail to a single location, and all
486 # subclasses can simply access self.ostream for writing.
479 # subclasses can simply access self.ostream for writing.
487 self._ostream = ostream
480 self._ostream = ostream
488
481
489 # Create color table
482 # Create color table
490 self.color_scheme_table = exception_colors()
483 self.color_scheme_table = exception_colors()
491
484
492 self.set_colors(color_scheme)
485 self.set_colors(color_scheme)
493 self.old_scheme = color_scheme # save initial value for toggles
486 self.old_scheme = color_scheme # save initial value for toggles
494
487
495 if call_pdb:
488 if call_pdb:
496 self.pdb = debugger.Pdb()
489 self.pdb = debugger.Pdb()
497 else:
490 else:
498 self.pdb = None
491 self.pdb = None
499
492
500 def _get_ostream(self):
493 def _get_ostream(self):
501 """Output stream that exceptions are written to.
494 """Output stream that exceptions are written to.
502
495
503 Valid values are:
496 Valid values are:
504
497
505 - None: the default, which means that IPython will dynamically resolve
498 - None: the default, which means that IPython will dynamically resolve
506 to sys.stdout. This ensures compatibility with most tools, including
499 to sys.stdout. This ensures compatibility with most tools, including
507 Windows (where plain stdout doesn't recognize ANSI escapes).
500 Windows (where plain stdout doesn't recognize ANSI escapes).
508
501
509 - Any object with 'write' and 'flush' attributes.
502 - Any object with 'write' and 'flush' attributes.
510 """
503 """
511 return sys.stdout if self._ostream is None else self._ostream
504 return sys.stdout if self._ostream is None else self._ostream
512
505
513 def _set_ostream(self, val):
506 def _set_ostream(self, val):
514 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
507 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
515 self._ostream = val
508 self._ostream = val
516
509
517 ostream = property(_get_ostream, _set_ostream)
510 ostream = property(_get_ostream, _set_ostream)
518
511
519 def set_colors(self, *args, **kw):
512 def set_colors(self, *args, **kw):
520 """Shorthand access to the color table scheme selector method."""
513 """Shorthand access to the color table scheme selector method."""
521
514
522 # Set own color table
515 # Set own color table
523 self.color_scheme_table.set_active_scheme(*args, **kw)
516 self.color_scheme_table.set_active_scheme(*args, **kw)
524 # for convenience, set Colors to the active scheme
517 # for convenience, set Colors to the active scheme
525 self.Colors = self.color_scheme_table.active_colors
518 self.Colors = self.color_scheme_table.active_colors
526 # Also set colors of debugger
519 # Also set colors of debugger
527 if hasattr(self, 'pdb') and self.pdb is not None:
520 if hasattr(self, 'pdb') and self.pdb is not None:
528 self.pdb.set_colors(*args, **kw)
521 self.pdb.set_colors(*args, **kw)
529
522
530 def color_toggle(self):
523 def color_toggle(self):
531 """Toggle between the currently active color scheme and NoColor."""
524 """Toggle between the currently active color scheme and NoColor."""
532
525
533 if self.color_scheme_table.active_scheme_name == 'NoColor':
526 if self.color_scheme_table.active_scheme_name == 'NoColor':
534 self.color_scheme_table.set_active_scheme(self.old_scheme)
527 self.color_scheme_table.set_active_scheme(self.old_scheme)
535 self.Colors = self.color_scheme_table.active_colors
528 self.Colors = self.color_scheme_table.active_colors
536 else:
529 else:
537 self.old_scheme = self.color_scheme_table.active_scheme_name
530 self.old_scheme = self.color_scheme_table.active_scheme_name
538 self.color_scheme_table.set_active_scheme('NoColor')
531 self.color_scheme_table.set_active_scheme('NoColor')
539 self.Colors = self.color_scheme_table.active_colors
532 self.Colors = self.color_scheme_table.active_colors
540
533
541 def stb2text(self, stb):
534 def stb2text(self, stb):
542 """Convert a structured traceback (a list) to a string."""
535 """Convert a structured traceback (a list) to a string."""
543 return '\n'.join(stb)
536 return '\n'.join(stb)
544
537
545 def text(self, etype, value, tb, tb_offset=None, context=5):
538 def text(self, etype, value, tb, tb_offset=None, context=5):
546 """Return formatted traceback.
539 """Return formatted traceback.
547
540
548 Subclasses may override this if they add extra arguments.
541 Subclasses may override this if they add extra arguments.
549 """
542 """
550 tb_list = self.structured_traceback(etype, value, tb,
543 tb_list = self.structured_traceback(etype, value, tb,
551 tb_offset, context)
544 tb_offset, context)
552 return self.stb2text(tb_list)
545 return self.stb2text(tb_list)
553
546
554 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
547 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
555 context=5, mode=None):
548 context=5, mode=None):
556 """Return a list of traceback frames.
549 """Return a list of traceback frames.
557
550
558 Must be implemented by each class.
551 Must be implemented by each class.
559 """
552 """
560 raise NotImplementedError()
553 raise NotImplementedError()
561
554
562
555
563 #---------------------------------------------------------------------------
556 #---------------------------------------------------------------------------
564 class ListTB(TBTools):
557 class ListTB(TBTools):
565 """Print traceback information from a traceback list, with optional color.
558 """Print traceback information from a traceback list, with optional color.
566
559
567 Calling requires 3 arguments: (etype, evalue, elist)
560 Calling requires 3 arguments: (etype, evalue, elist)
568 as would be obtained by::
561 as would be obtained by::
569
562
570 etype, evalue, tb = sys.exc_info()
563 etype, evalue, tb = sys.exc_info()
571 if tb:
564 if tb:
572 elist = traceback.extract_tb(tb)
565 elist = traceback.extract_tb(tb)
573 else:
566 else:
574 elist = None
567 elist = None
575
568
576 It can thus be used by programs which need to process the traceback before
569 It can thus be used by programs which need to process the traceback before
577 printing (such as console replacements based on the code module from the
570 printing (such as console replacements based on the code module from the
578 standard library).
571 standard library).
579
572
580 Because they are meant to be called without a full traceback (only a
573 Because they are meant to be called without a full traceback (only a
581 list), instances of this class can't call the interactive pdb debugger."""
574 list), instances of this class can't call the interactive pdb debugger."""
582
575
583 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
576 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
584 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
577 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
585 ostream=ostream, parent=parent,config=config)
578 ostream=ostream, parent=parent,config=config)
586
579
587 def __call__(self, etype, value, elist):
580 def __call__(self, etype, value, elist):
588 self.ostream.flush()
581 self.ostream.flush()
589 self.ostream.write(self.text(etype, value, elist))
582 self.ostream.write(self.text(etype, value, elist))
590 self.ostream.write('\n')
583 self.ostream.write('\n')
591
584
592 def structured_traceback(self, etype, value, elist, tb_offset=None,
585 def structured_traceback(self, etype, value, elist, tb_offset=None,
593 context=5):
586 context=5):
594 """Return a color formatted string with the traceback info.
587 """Return a color formatted string with the traceback info.
595
588
596 Parameters
589 Parameters
597 ----------
590 ----------
598 etype : exception type
591 etype : exception type
599 Type of the exception raised.
592 Type of the exception raised.
600
593
601 value : object
594 value : object
602 Data stored in the exception
595 Data stored in the exception
603
596
604 elist : list
597 elist : list
605 List of frames, see class docstring for details.
598 List of frames, see class docstring for details.
606
599
607 tb_offset : int, optional
600 tb_offset : int, optional
608 Number of frames in the traceback to skip. If not given, the
601 Number of frames in the traceback to skip. If not given, the
609 instance value is used (set in constructor).
602 instance value is used (set in constructor).
610
603
611 context : int, optional
604 context : int, optional
612 Number of lines of context information to print.
605 Number of lines of context information to print.
613
606
614 Returns
607 Returns
615 -------
608 -------
616 String with formatted exception.
609 String with formatted exception.
617 """
610 """
618 tb_offset = self.tb_offset if tb_offset is None else tb_offset
611 tb_offset = self.tb_offset if tb_offset is None else tb_offset
619 Colors = self.Colors
612 Colors = self.Colors
620 out_list = []
613 out_list = []
621 if elist:
614 if elist:
622
615
623 if tb_offset and len(elist) > tb_offset:
616 if tb_offset and len(elist) > tb_offset:
624 elist = elist[tb_offset:]
617 elist = elist[tb_offset:]
625
618
626 out_list.append('Traceback %s(most recent call last)%s:' %
619 out_list.append('Traceback %s(most recent call last)%s:' %
627 (Colors.normalEm, Colors.Normal) + '\n')
620 (Colors.normalEm, Colors.Normal) + '\n')
628 out_list.extend(self._format_list(elist))
621 out_list.extend(self._format_list(elist))
629 # The exception info should be a single entry in the list.
622 # The exception info should be a single entry in the list.
630 lines = ''.join(self._format_exception_only(etype, value))
623 lines = ''.join(self._format_exception_only(etype, value))
631 out_list.append(lines)
624 out_list.append(lines)
632
625
633 # Note: this code originally read:
626 # Note: this code originally read:
634
627
635 ## for line in lines[:-1]:
628 ## for line in lines[:-1]:
636 ## out_list.append(" "+line)
629 ## out_list.append(" "+line)
637 ## out_list.append(lines[-1])
630 ## out_list.append(lines[-1])
638
631
639 # This means it was indenting everything but the last line by a little
632 # This means it was indenting everything but the last line by a little
640 # bit. I've disabled this for now, but if we see ugliness somewhere we
633 # bit. I've disabled this for now, but if we see ugliness somewhere we
641 # can restore it.
634 # can restore it.
642
635
643 return out_list
636 return out_list
644
637
645 def _format_list(self, extracted_list):
638 def _format_list(self, extracted_list):
646 """Format a list of traceback entry tuples for printing.
639 """Format a list of traceback entry tuples for printing.
647
640
648 Given a list of tuples as returned by extract_tb() or
641 Given a list of tuples as returned by extract_tb() or
649 extract_stack(), return a list of strings ready for printing.
642 extract_stack(), return a list of strings ready for printing.
650 Each string in the resulting list corresponds to the item with the
643 Each string in the resulting list corresponds to the item with the
651 same index in the argument list. Each string ends in a newline;
644 same index in the argument list. Each string ends in a newline;
652 the strings may contain internal newlines as well, for those items
645 the strings may contain internal newlines as well, for those items
653 whose source text line is not None.
646 whose source text line is not None.
654
647
655 Lifted almost verbatim from traceback.py
648 Lifted almost verbatim from traceback.py
656 """
649 """
657
650
658 Colors = self.Colors
651 Colors = self.Colors
659 list = []
652 list = []
660 for filename, lineno, name, line in extracted_list[:-1]:
653 for filename, lineno, name, line in extracted_list[:-1]:
661 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
654 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
662 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
655 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
663 Colors.lineno, lineno, Colors.Normal,
656 Colors.lineno, lineno, Colors.Normal,
664 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
657 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
665 if line:
658 if line:
666 item += ' %s\n' % line.strip()
659 item += ' %s\n' % line.strip()
667 list.append(item)
660 list.append(item)
668 # Emphasize the last entry
661 # Emphasize the last entry
669 filename, lineno, name, line = extracted_list[-1]
662 filename, lineno, name, line = extracted_list[-1]
670 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
663 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
671 (Colors.normalEm,
664 (Colors.normalEm,
672 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
665 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
673 Colors.linenoEm, lineno, Colors.normalEm,
666 Colors.linenoEm, lineno, Colors.normalEm,
674 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
667 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
675 Colors.Normal)
668 Colors.Normal)
676 if line:
669 if line:
677 item += '%s %s%s\n' % (Colors.line, line.strip(),
670 item += '%s %s%s\n' % (Colors.line, line.strip(),
678 Colors.Normal)
671 Colors.Normal)
679 list.append(item)
672 list.append(item)
680 return list
673 return list
681
674
682 def _format_exception_only(self, etype, value):
675 def _format_exception_only(self, etype, value):
683 """Format the exception part of a traceback.
676 """Format the exception part of a traceback.
684
677
685 The arguments are the exception type and value such as given by
678 The arguments are the exception type and value such as given by
686 sys.exc_info()[:2]. The return value is a list of strings, each ending
679 sys.exc_info()[:2]. The return value is a list of strings, each ending
687 in a newline. Normally, the list contains a single string; however,
680 in a newline. Normally, the list contains a single string; however,
688 for SyntaxError exceptions, it contains several lines that (when
681 for SyntaxError exceptions, it contains several lines that (when
689 printed) display detailed information about where the syntax error
682 printed) display detailed information about where the syntax error
690 occurred. The message indicating which exception occurred is the
683 occurred. The message indicating which exception occurred is the
691 always last string in the list.
684 always last string in the list.
692
685
693 Also lifted nearly verbatim from traceback.py
686 Also lifted nearly verbatim from traceback.py
694 """
687 """
695 have_filedata = False
688 have_filedata = False
696 Colors = self.Colors
689 Colors = self.Colors
697 list = []
690 list = []
698 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
691 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
699 if value is None:
692 if value is None:
700 # Not sure if this can still happen in Python 2.6 and above
693 # Not sure if this can still happen in Python 2.6 and above
701 list.append(stype + '\n')
694 list.append(stype + '\n')
702 else:
695 else:
703 if issubclass(etype, SyntaxError):
696 if issubclass(etype, SyntaxError):
704 have_filedata = True
697 have_filedata = True
705 if not value.filename: value.filename = "<string>"
698 if not value.filename: value.filename = "<string>"
706 if value.lineno:
699 if value.lineno:
707 lineno = value.lineno
700 lineno = value.lineno
708 textline = linecache.getline(value.filename, value.lineno)
701 textline = linecache.getline(value.filename, value.lineno)
709 else:
702 else:
710 lineno = 'unknown'
703 lineno = 'unknown'
711 textline = ''
704 textline = ''
712 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
705 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
713 (Colors.normalEm,
706 (Colors.normalEm,
714 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
707 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
715 Colors.linenoEm, lineno, Colors.Normal ))
708 Colors.linenoEm, lineno, Colors.Normal ))
716 if textline == '':
709 if textline == '':
717 textline = py3compat.cast_unicode(value.text, "utf-8")
710 textline = py3compat.cast_unicode(value.text, "utf-8")
718
711
719 if textline is not None:
712 if textline is not None:
720 i = 0
713 i = 0
721 while i < len(textline) and textline[i].isspace():
714 while i < len(textline) and textline[i].isspace():
722 i += 1
715 i += 1
723 list.append('%s %s%s\n' % (Colors.line,
716 list.append('%s %s%s\n' % (Colors.line,
724 textline.strip(),
717 textline.strip(),
725 Colors.Normal))
718 Colors.Normal))
726 if value.offset is not None:
719 if value.offset is not None:
727 s = ' '
720 s = ' '
728 for c in textline[i:value.offset - 1]:
721 for c in textline[i:value.offset - 1]:
729 if c.isspace():
722 if c.isspace():
730 s += c
723 s += c
731 else:
724 else:
732 s += ' '
725 s += ' '
733 list.append('%s%s^%s\n' % (Colors.caret, s,
726 list.append('%s%s^%s\n' % (Colors.caret, s,
734 Colors.Normal))
727 Colors.Normal))
735
728
736 try:
729 try:
737 s = value.msg
730 s = value.msg
738 except Exception:
731 except Exception:
739 s = self._some_str(value)
732 s = self._some_str(value)
740 if s:
733 if s:
741 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
734 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
742 Colors.Normal, s))
735 Colors.Normal, s))
743 else:
736 else:
744 list.append('%s\n' % stype)
737 list.append('%s\n' % stype)
745
738
746 # sync with user hooks
739 # sync with user hooks
747 if have_filedata:
740 if have_filedata:
748 ipinst = get_ipython()
741 ipinst = get_ipython()
749 if ipinst is not None:
742 if ipinst is not None:
750 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
743 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
751
744
752 return list
745 return list
753
746
754 def get_exception_only(self, etype, value):
747 def get_exception_only(self, etype, value):
755 """Only print the exception type and message, without a traceback.
748 """Only print the exception type and message, without a traceback.
756
749
757 Parameters
750 Parameters
758 ----------
751 ----------
759 etype : exception type
752 etype : exception type
760 value : exception value
753 value : exception value
761 """
754 """
762 return ListTB.structured_traceback(self, etype, value, [])
755 return ListTB.structured_traceback(self, etype, value, [])
763
756
764 def show_exception_only(self, etype, evalue):
757 def show_exception_only(self, etype, evalue):
765 """Only print the exception type and message, without a traceback.
758 """Only print the exception type and message, without a traceback.
766
759
767 Parameters
760 Parameters
768 ----------
761 ----------
769 etype : exception type
762 etype : exception type
770 value : exception value
763 value : exception value
771 """
764 """
772 # This method needs to use __call__ from *this* class, not the one from
765 # This method needs to use __call__ from *this* class, not the one from
773 # a subclass whose signature or behavior may be different
766 # a subclass whose signature or behavior may be different
774 ostream = self.ostream
767 ostream = self.ostream
775 ostream.flush()
768 ostream.flush()
776 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
769 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
777 ostream.flush()
770 ostream.flush()
778
771
779 def _some_str(self, value):
772 def _some_str(self, value):
780 # Lifted from traceback.py
773 # Lifted from traceback.py
781 try:
774 try:
782 return py3compat.cast_unicode(str(value))
775 return py3compat.cast_unicode(str(value))
783 except:
776 except:
784 return u'<unprintable %s object>' % type(value).__name__
777 return u'<unprintable %s object>' % type(value).__name__
785
778
786
779
787 #----------------------------------------------------------------------------
780 #----------------------------------------------------------------------------
788 class VerboseTB(TBTools):
781 class VerboseTB(TBTools):
789 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
782 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
790 of HTML. Requires inspect and pydoc. Crazy, man.
783 of HTML. Requires inspect and pydoc. Crazy, man.
791
784
792 Modified version which optionally strips the topmost entries from the
785 Modified version which optionally strips the topmost entries from the
793 traceback, to be used with alternate interpreters (because their own code
786 traceback, to be used with alternate interpreters (because their own code
794 would appear in the traceback)."""
787 would appear in the traceback)."""
795
788
796 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
789 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
797 tb_offset=0, long_header=False, include_vars=True,
790 tb_offset=0, long_header=False, include_vars=True,
798 check_cache=None, debugger_cls = None,
791 check_cache=None, debugger_cls = None,
799 parent=None, config=None):
792 parent=None, config=None):
800 """Specify traceback offset, headers and color scheme.
793 """Specify traceback offset, headers and color scheme.
801
794
802 Define how many frames to drop from the tracebacks. Calling it with
795 Define how many frames to drop from the tracebacks. Calling it with
803 tb_offset=1 allows use of this handler in interpreters which will have
796 tb_offset=1 allows use of this handler in interpreters which will have
804 their own code at the top of the traceback (VerboseTB will first
797 their own code at the top of the traceback (VerboseTB will first
805 remove that frame before printing the traceback info)."""
798 remove that frame before printing the traceback info)."""
806 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
799 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
807 ostream=ostream, parent=parent, config=config)
800 ostream=ostream, parent=parent, config=config)
808 self.tb_offset = tb_offset
801 self.tb_offset = tb_offset
809 self.long_header = long_header
802 self.long_header = long_header
810 self.include_vars = include_vars
803 self.include_vars = include_vars
811 # By default we use linecache.checkcache, but the user can provide a
804 # By default we use linecache.checkcache, but the user can provide a
812 # different check_cache implementation. This is used by the IPython
805 # different check_cache implementation. This is used by the IPython
813 # kernel to provide tracebacks for interactive code that is cached,
806 # kernel to provide tracebacks for interactive code that is cached,
814 # by a compiler instance that flushes the linecache but preserves its
807 # by a compiler instance that flushes the linecache but preserves its
815 # own code cache.
808 # own code cache.
816 if check_cache is None:
809 if check_cache is None:
817 check_cache = linecache.checkcache
810 check_cache = linecache.checkcache
818 self.check_cache = check_cache
811 self.check_cache = check_cache
819
812
820 self.debugger_cls = debugger_cls or debugger.Pdb
813 self.debugger_cls = debugger_cls or debugger.Pdb
821
814
822 def format_records(self, records, last_unique, recursion_repeat):
815 def format_records(self, records, last_unique, recursion_repeat):
823 """Format the stack frames of the traceback"""
816 """Format the stack frames of the traceback"""
824 frames = []
817 frames = []
825 for r in records[:last_unique+recursion_repeat+1]:
818 for r in records[:last_unique+recursion_repeat+1]:
826 #print '*** record:',file,lnum,func,lines,index # dbg
819 #print '*** record:',file,lnum,func,lines,index # dbg
827 frames.append(self.format_record(*r))
820 frames.append(self.format_record(*r))
828
821
829 if recursion_repeat:
822 if recursion_repeat:
830 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
823 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
831 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
824 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
832
825
833 return frames
826 return frames
834
827
835 def format_record(self, frame, file, lnum, func, lines, index):
828 def format_record(self, frame, file, lnum, func, lines, index):
836 """Format a single stack frame"""
829 """Format a single stack frame"""
837 Colors = self.Colors # just a shorthand + quicker name lookup
830 Colors = self.Colors # just a shorthand + quicker name lookup
838 ColorsNormal = Colors.Normal # used a lot
831 ColorsNormal = Colors.Normal # used a lot
839 col_scheme = self.color_scheme_table.active_scheme_name
832 col_scheme = self.color_scheme_table.active_scheme_name
840 indent = ' ' * INDENT_SIZE
833 indent = ' ' * INDENT_SIZE
841 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
834 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
842 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
835 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
843 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
836 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
844 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
837 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
845 ColorsNormal)
838 ColorsNormal)
846 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
839 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
847 (Colors.vName, Colors.valEm, ColorsNormal)
840 (Colors.vName, Colors.valEm, ColorsNormal)
848 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
841 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
849 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
842 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
850 Colors.vName, ColorsNormal)
843 Colors.vName, ColorsNormal)
851 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
844 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
852
845
853 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
846 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
854 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
847 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
855 ColorsNormal)
848 ColorsNormal)
856
849
857 abspath = os.path.abspath
850 abspath = os.path.abspath
858
851
859
852
860 if not file:
853 if not file:
861 file = '?'
854 file = '?'
862 elif file.startswith(str("<")) and file.endswith(str(">")):
855 elif file.startswith(str("<")) and file.endswith(str(">")):
863 # Not a real filename, no problem...
856 # Not a real filename, no problem...
864 pass
857 pass
865 elif not os.path.isabs(file):
858 elif not os.path.isabs(file):
866 # Try to make the filename absolute by trying all
859 # Try to make the filename absolute by trying all
867 # sys.path entries (which is also what linecache does)
860 # sys.path entries (which is also what linecache does)
868 for dirname in sys.path:
861 for dirname in sys.path:
869 try:
862 try:
870 fullname = os.path.join(dirname, file)
863 fullname = os.path.join(dirname, file)
871 if os.path.isfile(fullname):
864 if os.path.isfile(fullname):
872 file = os.path.abspath(fullname)
865 file = os.path.abspath(fullname)
873 break
866 break
874 except Exception:
867 except Exception:
875 # Just in case that sys.path contains very
868 # Just in case that sys.path contains very
876 # strange entries...
869 # strange entries...
877 pass
870 pass
878
871
879 file = py3compat.cast_unicode(file, util_path.fs_encoding)
872 file = py3compat.cast_unicode(file, util_path.fs_encoding)
880 link = tpl_link % file
873 link = tpl_link % file
881 args, varargs, varkw, locals = fixed_getargvalues(frame)
874 args, varargs, varkw, locals = inspect.getargvalues(frame)
882
875
883 if func == '?':
876 if func == '?':
884 call = ''
877 call = ''
885 else:
878 else:
886 # Decide whether to include variable details or not
879 # Decide whether to include variable details or not
887 var_repr = self.include_vars and eqrepr or nullrepr
880 var_repr = self.include_vars and eqrepr or nullrepr
888 try:
881 try:
889 call = tpl_call % (func, inspect.formatargvalues(args,
882 call = tpl_call % (func, inspect.formatargvalues(args,
890 varargs, varkw,
883 varargs, varkw,
891 locals, formatvalue=var_repr))
884 locals, formatvalue=var_repr))
892 except KeyError:
885 except KeyError:
893 # This happens in situations like errors inside generator
886 # This happens in situations like errors inside generator
894 # expressions, where local variables are listed in the
887 # expressions, where local variables are listed in the
895 # line, but can't be extracted from the frame. I'm not
888 # line, but can't be extracted from the frame. I'm not
896 # 100% sure this isn't actually a bug in inspect itself,
889 # 100% sure this isn't actually a bug in inspect itself,
897 # but since there's no info for us to compute with, the
890 # but since there's no info for us to compute with, the
898 # best we can do is report the failure and move on. Here
891 # best we can do is report the failure and move on. Here
899 # we must *not* call any traceback construction again,
892 # we must *not* call any traceback construction again,
900 # because that would mess up use of %debug later on. So we
893 # because that would mess up use of %debug later on. So we
901 # simply report the failure and move on. The only
894 # simply report the failure and move on. The only
902 # limitation will be that this frame won't have locals
895 # limitation will be that this frame won't have locals
903 # listed in the call signature. Quite subtle problem...
896 # listed in the call signature. Quite subtle problem...
904 # I can't think of a good way to validate this in a unit
897 # I can't think of a good way to validate this in a unit
905 # test, but running a script consisting of:
898 # test, but running a script consisting of:
906 # dict( (k,v.strip()) for (k,v) in range(10) )
899 # dict( (k,v.strip()) for (k,v) in range(10) )
907 # will illustrate the error, if this exception catch is
900 # will illustrate the error, if this exception catch is
908 # disabled.
901 # disabled.
909 call = tpl_call_fail % func
902 call = tpl_call_fail % func
910
903
911 # Don't attempt to tokenize binary files.
904 # Don't attempt to tokenize binary files.
912 if file.endswith(('.so', '.pyd', '.dll')):
905 if file.endswith(('.so', '.pyd', '.dll')):
913 return '%s %s\n' % (link, call)
906 return '%s %s\n' % (link, call)
914
907
915 elif file.endswith(('.pyc', '.pyo')):
908 elif file.endswith(('.pyc', '.pyo')):
916 # Look up the corresponding source file.
909 # Look up the corresponding source file.
917 try:
910 try:
918 file = openpy.source_from_cache(file)
911 file = openpy.source_from_cache(file)
919 except ValueError:
912 except ValueError:
920 # Failed to get the source file for some reason
913 # Failed to get the source file for some reason
921 # E.g. https://github.com/ipython/ipython/issues/9486
914 # E.g. https://github.com/ipython/ipython/issues/9486
922 return '%s %s\n' % (link, call)
915 return '%s %s\n' % (link, call)
923
916
924 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
917 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
925 line = getline(file, lnum[0])
918 line = getline(file, lnum[0])
926 lnum[0] += 1
919 lnum[0] += 1
927 return line
920 return line
928
921
929 # Build the list of names on this line of code where the exception
922 # Build the list of names on this line of code where the exception
930 # occurred.
923 # occurred.
931 try:
924 try:
932 names = []
925 names = []
933 name_cont = False
926 name_cont = False
934
927
935 for token_type, token, start, end, line in generate_tokens(linereader):
928 for token_type, token, start, end, line in generate_tokens(linereader):
936 # build composite names
929 # build composite names
937 if token_type == tokenize.NAME and token not in keyword.kwlist:
930 if token_type == tokenize.NAME and token not in keyword.kwlist:
938 if name_cont:
931 if name_cont:
939 # Continuation of a dotted name
932 # Continuation of a dotted name
940 try:
933 try:
941 names[-1].append(token)
934 names[-1].append(token)
942 except IndexError:
935 except IndexError:
943 names.append([token])
936 names.append([token])
944 name_cont = False
937 name_cont = False
945 else:
938 else:
946 # Regular new names. We append everything, the caller
939 # Regular new names. We append everything, the caller
947 # will be responsible for pruning the list later. It's
940 # will be responsible for pruning the list later. It's
948 # very tricky to try to prune as we go, b/c composite
941 # very tricky to try to prune as we go, b/c composite
949 # names can fool us. The pruning at the end is easy
942 # names can fool us. The pruning at the end is easy
950 # to do (or the caller can print a list with repeated
943 # to do (or the caller can print a list with repeated
951 # names if so desired.
944 # names if so desired.
952 names.append([token])
945 names.append([token])
953 elif token == '.':
946 elif token == '.':
954 name_cont = True
947 name_cont = True
955 elif token_type == tokenize.NEWLINE:
948 elif token_type == tokenize.NEWLINE:
956 break
949 break
957
950
958 except (IndexError, UnicodeDecodeError, SyntaxError):
951 except (IndexError, UnicodeDecodeError, SyntaxError):
959 # signals exit of tokenizer
952 # signals exit of tokenizer
960 # SyntaxError can occur if the file is not actually Python
953 # SyntaxError can occur if the file is not actually Python
961 # - see gh-6300
954 # - see gh-6300
962 pass
955 pass
963 except tokenize.TokenError as msg:
956 except tokenize.TokenError as msg:
964 _m = ("An unexpected error occurred while tokenizing input\n"
957 _m = ("An unexpected error occurred while tokenizing input\n"
965 "The following traceback may be corrupted or invalid\n"
958 "The following traceback may be corrupted or invalid\n"
966 "The error message is: %s\n" % msg)
959 "The error message is: %s\n" % msg)
967 error(_m)
960 error(_m)
968
961
969 # Join composite names (e.g. "dict.fromkeys")
962 # Join composite names (e.g. "dict.fromkeys")
970 names = ['.'.join(n) for n in names]
963 names = ['.'.join(n) for n in names]
971 # prune names list of duplicates, but keep the right order
964 # prune names list of duplicates, but keep the right order
972 unique_names = uniq_stable(names)
965 unique_names = uniq_stable(names)
973
966
974 # Start loop over vars
967 # Start loop over vars
975 lvals = []
968 lvals = []
976 if self.include_vars:
969 if self.include_vars:
977 for name_full in unique_names:
970 for name_full in unique_names:
978 name_base = name_full.split('.', 1)[0]
971 name_base = name_full.split('.', 1)[0]
979 if name_base in frame.f_code.co_varnames:
972 if name_base in frame.f_code.co_varnames:
980 if name_base in locals:
973 if name_base in locals:
981 try:
974 try:
982 value = repr(eval(name_full, locals))
975 value = repr(eval(name_full, locals))
983 except:
976 except:
984 value = undefined
977 value = undefined
985 else:
978 else:
986 value = undefined
979 value = undefined
987 name = tpl_local_var % name_full
980 name = tpl_local_var % name_full
988 else:
981 else:
989 if name_base in frame.f_globals:
982 if name_base in frame.f_globals:
990 try:
983 try:
991 value = repr(eval(name_full, frame.f_globals))
984 value = repr(eval(name_full, frame.f_globals))
992 except:
985 except:
993 value = undefined
986 value = undefined
994 else:
987 else:
995 value = undefined
988 value = undefined
996 name = tpl_global_var % name_full
989 name = tpl_global_var % name_full
997 lvals.append(tpl_name_val % (name, value))
990 lvals.append(tpl_name_val % (name, value))
998 if lvals:
991 if lvals:
999 lvals = '%s%s' % (indent, em_normal.join(lvals))
992 lvals = '%s%s' % (indent, em_normal.join(lvals))
1000 else:
993 else:
1001 lvals = ''
994 lvals = ''
1002
995
1003 level = '%s %s\n' % (link, call)
996 level = '%s %s\n' % (link, call)
1004
997
1005 if index is None:
998 if index is None:
1006 return level
999 return level
1007 else:
1000 else:
1008 _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2
1001 _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2
1009 return '%s%s' % (level, ''.join(
1002 return '%s%s' % (level, ''.join(
1010 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1003 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1011 _line_format)))
1004 _line_format)))
1012
1005
1013 def prepare_chained_exception_message(self, cause):
1006 def prepare_chained_exception_message(self, cause):
1014 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1007 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1015 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1008 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1016
1009
1017 if cause:
1010 if cause:
1018 message = [[direct_cause]]
1011 message = [[direct_cause]]
1019 else:
1012 else:
1020 message = [[exception_during_handling]]
1013 message = [[exception_during_handling]]
1021 return message
1014 return message
1022
1015
1023 def prepare_header(self, etype, long_version=False):
1016 def prepare_header(self, etype, long_version=False):
1024 colors = self.Colors # just a shorthand + quicker name lookup
1017 colors = self.Colors # just a shorthand + quicker name lookup
1025 colorsnormal = colors.Normal # used a lot
1018 colorsnormal = colors.Normal # used a lot
1026 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1019 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1027 width = min(75, get_terminal_size()[0])
1020 width = min(75, get_terminal_size()[0])
1028 if long_version:
1021 if long_version:
1029 # Header with the exception type, python version, and date
1022 # Header with the exception type, python version, and date
1030 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1023 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1031 date = time.ctime(time.time())
1024 date = time.ctime(time.time())
1032
1025
1033 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
1026 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
1034 exc, ' ' * (width - len(str(etype)) - len(pyver)),
1027 exc, ' ' * (width - len(str(etype)) - len(pyver)),
1035 pyver, date.rjust(width) )
1028 pyver, date.rjust(width) )
1036 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1029 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1037 "\ncalls leading up to the error, with the most recent (innermost) call last."
1030 "\ncalls leading up to the error, with the most recent (innermost) call last."
1038 else:
1031 else:
1039 # Simplified header
1032 # Simplified header
1040 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1033 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1041 rjust(width - len(str(etype))) )
1034 rjust(width - len(str(etype))) )
1042
1035
1043 return head
1036 return head
1044
1037
1045 def format_exception(self, etype, evalue):
1038 def format_exception(self, etype, evalue):
1046 colors = self.Colors # just a shorthand + quicker name lookup
1039 colors = self.Colors # just a shorthand + quicker name lookup
1047 colorsnormal = colors.Normal # used a lot
1040 colorsnormal = colors.Normal # used a lot
1048 indent = ' ' * INDENT_SIZE
1041 indent = ' ' * INDENT_SIZE
1049 # Get (safely) a string form of the exception info
1042 # Get (safely) a string form of the exception info
1050 try:
1043 try:
1051 etype_str, evalue_str = map(str, (etype, evalue))
1044 etype_str, evalue_str = map(str, (etype, evalue))
1052 except:
1045 except:
1053 # User exception is improperly defined.
1046 # User exception is improperly defined.
1054 etype, evalue = str, sys.exc_info()[:2]
1047 etype, evalue = str, sys.exc_info()[:2]
1055 etype_str, evalue_str = map(str, (etype, evalue))
1048 etype_str, evalue_str = map(str, (etype, evalue))
1056 # ... and format it
1049 # ... and format it
1057 return ['%s%s%s: %s' % (colors.excName, etype_str,
1050 return ['%s%s%s: %s' % (colors.excName, etype_str,
1058 colorsnormal, py3compat.cast_unicode(evalue_str))]
1051 colorsnormal, py3compat.cast_unicode(evalue_str))]
1059
1052
1060 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1053 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1061 """Formats the header, traceback and exception message for a single exception.
1054 """Formats the header, traceback and exception message for a single exception.
1062
1055
1063 This may be called multiple times by Python 3 exception chaining
1056 This may be called multiple times by Python 3 exception chaining
1064 (PEP 3134).
1057 (PEP 3134).
1065 """
1058 """
1066 # some locals
1059 # some locals
1067 orig_etype = etype
1060 orig_etype = etype
1068 try:
1061 try:
1069 etype = etype.__name__
1062 etype = etype.__name__
1070 except AttributeError:
1063 except AttributeError:
1071 pass
1064 pass
1072
1065
1073 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1066 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1074 head = self.prepare_header(etype, self.long_header)
1067 head = self.prepare_header(etype, self.long_header)
1075 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1068 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1076
1069
1077 if records is None:
1070 if records is None:
1078 return ""
1071 return ""
1079
1072
1080 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1073 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1081
1074
1082 frames = self.format_records(records, last_unique, recursion_repeat)
1075 frames = self.format_records(records, last_unique, recursion_repeat)
1083
1076
1084 formatted_exception = self.format_exception(etype, evalue)
1077 formatted_exception = self.format_exception(etype, evalue)
1085 if records:
1078 if records:
1086 filepath, lnum = records[-1][1:3]
1079 filepath, lnum = records[-1][1:3]
1087 filepath = os.path.abspath(filepath)
1080 filepath = os.path.abspath(filepath)
1088 ipinst = get_ipython()
1081 ipinst = get_ipython()
1089 if ipinst is not None:
1082 if ipinst is not None:
1090 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1083 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1091
1084
1092 return [[head] + frames + [''.join(formatted_exception[0])]]
1085 return [[head] + frames + [''.join(formatted_exception[0])]]
1093
1086
1094 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1087 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1095 try:
1088 try:
1096 # Try the default getinnerframes and Alex's: Alex's fixes some
1089 # Try the default getinnerframes and Alex's: Alex's fixes some
1097 # problems, but it generates empty tracebacks for console errors
1090 # problems, but it generates empty tracebacks for console errors
1098 # (5 blanks lines) where none should be returned.
1091 # (5 blanks lines) where none should be returned.
1099 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1092 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1100 except UnicodeDecodeError:
1093 except UnicodeDecodeError:
1101 # This can occur if a file's encoding magic comment is wrong.
1094 # This can occur if a file's encoding magic comment is wrong.
1102 # I can't see a way to recover without duplicating a bunch of code
1095 # I can't see a way to recover without duplicating a bunch of code
1103 # from the stdlib traceback module. --TK
1096 # from the stdlib traceback module. --TK
1104 error('\nUnicodeDecodeError while processing traceback.\n')
1097 error('\nUnicodeDecodeError while processing traceback.\n')
1105 return None
1098 return None
1106 except:
1099 except:
1107 # FIXME: I've been getting many crash reports from python 2.3
1100 # FIXME: I've been getting many crash reports from python 2.3
1108 # users, traceable to inspect.py. If I can find a small test-case
1101 # users, traceable to inspect.py. If I can find a small test-case
1109 # to reproduce this, I should either write a better workaround or
1102 # to reproduce this, I should either write a better workaround or
1110 # file a bug report against inspect (if that's the real problem).
1103 # file a bug report against inspect (if that's the real problem).
1111 # So far, I haven't been able to find an isolated example to
1104 # So far, I haven't been able to find an isolated example to
1112 # reproduce the problem.
1105 # reproduce the problem.
1113 inspect_error()
1106 inspect_error()
1114 traceback.print_exc(file=self.ostream)
1107 traceback.print_exc(file=self.ostream)
1115 info('\nUnfortunately, your original traceback can not be constructed.\n')
1108 info('\nUnfortunately, your original traceback can not be constructed.\n')
1116 return None
1109 return None
1117
1110
1118 def get_parts_of_chained_exception(self, evalue):
1111 def get_parts_of_chained_exception(self, evalue):
1119 def get_chained_exception(exception_value):
1112 def get_chained_exception(exception_value):
1120 cause = getattr(exception_value, '__cause__', None)
1113 cause = getattr(exception_value, '__cause__', None)
1121 if cause:
1114 if cause:
1122 return cause
1115 return cause
1123 if getattr(exception_value, '__suppress_context__', False):
1116 if getattr(exception_value, '__suppress_context__', False):
1124 return None
1117 return None
1125 return getattr(exception_value, '__context__', None)
1118 return getattr(exception_value, '__context__', None)
1126
1119
1127 chained_evalue = get_chained_exception(evalue)
1120 chained_evalue = get_chained_exception(evalue)
1128
1121
1129 if chained_evalue:
1122 if chained_evalue:
1130 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1123 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1131
1124
1132 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1125 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1133 number_of_lines_of_context=5):
1126 number_of_lines_of_context=5):
1134 """Return a nice text document describing the traceback."""
1127 """Return a nice text document describing the traceback."""
1135
1128
1136 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1129 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1137 tb_offset)
1130 tb_offset)
1138
1131
1139 colors = self.Colors # just a shorthand + quicker name lookup
1132 colors = self.Colors # just a shorthand + quicker name lookup
1140 colorsnormal = colors.Normal # used a lot
1133 colorsnormal = colors.Normal # used a lot
1141 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1134 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1142 structured_traceback_parts = [head]
1135 structured_traceback_parts = [head]
1143 if py3compat.PY3:
1136 if py3compat.PY3:
1144 chained_exceptions_tb_offset = 0
1137 chained_exceptions_tb_offset = 0
1145 lines_of_context = 3
1138 lines_of_context = 3
1146 formatted_exceptions = formatted_exception
1139 formatted_exceptions = formatted_exception
1147 exception = self.get_parts_of_chained_exception(evalue)
1140 exception = self.get_parts_of_chained_exception(evalue)
1148 if exception:
1141 if exception:
1149 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1142 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1150 etype, evalue, etb = exception
1143 etype, evalue, etb = exception
1151 else:
1144 else:
1152 evalue = None
1145 evalue = None
1153 chained_exc_ids = set()
1146 chained_exc_ids = set()
1154 while evalue:
1147 while evalue:
1155 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1148 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1156 chained_exceptions_tb_offset)
1149 chained_exceptions_tb_offset)
1157 exception = self.get_parts_of_chained_exception(evalue)
1150 exception = self.get_parts_of_chained_exception(evalue)
1158
1151
1159 if exception and not id(exception[1]) in chained_exc_ids:
1152 if exception and not id(exception[1]) in chained_exc_ids:
1160 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1153 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1161 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1154 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1162 etype, evalue, etb = exception
1155 etype, evalue, etb = exception
1163 else:
1156 else:
1164 evalue = None
1157 evalue = None
1165
1158
1166 # we want to see exceptions in a reversed order:
1159 # we want to see exceptions in a reversed order:
1167 # the first exception should be on top
1160 # the first exception should be on top
1168 for formatted_exception in reversed(formatted_exceptions):
1161 for formatted_exception in reversed(formatted_exceptions):
1169 structured_traceback_parts += formatted_exception
1162 structured_traceback_parts += formatted_exception
1170 else:
1163 else:
1171 structured_traceback_parts += formatted_exception[0]
1164 structured_traceback_parts += formatted_exception[0]
1172
1165
1173 return structured_traceback_parts
1166 return structured_traceback_parts
1174
1167
1175 def debugger(self, force=False):
1168 def debugger(self, force=False):
1176 """Call up the pdb debugger if desired, always clean up the tb
1169 """Call up the pdb debugger if desired, always clean up the tb
1177 reference.
1170 reference.
1178
1171
1179 Keywords:
1172 Keywords:
1180
1173
1181 - force(False): by default, this routine checks the instance call_pdb
1174 - force(False): by default, this routine checks the instance call_pdb
1182 flag and does not actually invoke the debugger if the flag is false.
1175 flag and does not actually invoke the debugger if the flag is false.
1183 The 'force' option forces the debugger to activate even if the flag
1176 The 'force' option forces the debugger to activate even if the flag
1184 is false.
1177 is false.
1185
1178
1186 If the call_pdb flag is set, the pdb interactive debugger is
1179 If the call_pdb flag is set, the pdb interactive debugger is
1187 invoked. In all cases, the self.tb reference to the current traceback
1180 invoked. In all cases, the self.tb reference to the current traceback
1188 is deleted to prevent lingering references which hamper memory
1181 is deleted to prevent lingering references which hamper memory
1189 management.
1182 management.
1190
1183
1191 Note that each call to pdb() does an 'import readline', so if your app
1184 Note that each call to pdb() does an 'import readline', so if your app
1192 requires a special setup for the readline completers, you'll have to
1185 requires a special setup for the readline completers, you'll have to
1193 fix that by hand after invoking the exception handler."""
1186 fix that by hand after invoking the exception handler."""
1194
1187
1195 if force or self.call_pdb:
1188 if force or self.call_pdb:
1196 if self.pdb is None:
1189 if self.pdb is None:
1197 self.pdb = self.debugger_cls()
1190 self.pdb = self.debugger_cls()
1198 # the system displayhook may have changed, restore the original
1191 # the system displayhook may have changed, restore the original
1199 # for pdb
1192 # for pdb
1200 display_trap = DisplayTrap(hook=sys.__displayhook__)
1193 display_trap = DisplayTrap(hook=sys.__displayhook__)
1201 with display_trap:
1194 with display_trap:
1202 self.pdb.reset()
1195 self.pdb.reset()
1203 # Find the right frame so we don't pop up inside ipython itself
1196 # Find the right frame so we don't pop up inside ipython itself
1204 if hasattr(self, 'tb') and self.tb is not None:
1197 if hasattr(self, 'tb') and self.tb is not None:
1205 etb = self.tb
1198 etb = self.tb
1206 else:
1199 else:
1207 etb = self.tb = sys.last_traceback
1200 etb = self.tb = sys.last_traceback
1208 while self.tb is not None and self.tb.tb_next is not None:
1201 while self.tb is not None and self.tb.tb_next is not None:
1209 self.tb = self.tb.tb_next
1202 self.tb = self.tb.tb_next
1210 if etb and etb.tb_next:
1203 if etb and etb.tb_next:
1211 etb = etb.tb_next
1204 etb = etb.tb_next
1212 self.pdb.botframe = etb.tb_frame
1205 self.pdb.botframe = etb.tb_frame
1213 self.pdb.interaction(self.tb.tb_frame, self.tb)
1206 self.pdb.interaction(self.tb.tb_frame, self.tb)
1214
1207
1215 if hasattr(self, 'tb'):
1208 if hasattr(self, 'tb'):
1216 del self.tb
1209 del self.tb
1217
1210
1218 def handler(self, info=None):
1211 def handler(self, info=None):
1219 (etype, evalue, etb) = info or sys.exc_info()
1212 (etype, evalue, etb) = info or sys.exc_info()
1220 self.tb = etb
1213 self.tb = etb
1221 ostream = self.ostream
1214 ostream = self.ostream
1222 ostream.flush()
1215 ostream.flush()
1223 ostream.write(self.text(etype, evalue, etb))
1216 ostream.write(self.text(etype, evalue, etb))
1224 ostream.write('\n')
1217 ostream.write('\n')
1225 ostream.flush()
1218 ostream.flush()
1226
1219
1227 # Changed so an instance can just be called as VerboseTB_inst() and print
1220 # Changed so an instance can just be called as VerboseTB_inst() and print
1228 # out the right info on its own.
1221 # out the right info on its own.
1229 def __call__(self, etype=None, evalue=None, etb=None):
1222 def __call__(self, etype=None, evalue=None, etb=None):
1230 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1223 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1231 if etb is None:
1224 if etb is None:
1232 self.handler()
1225 self.handler()
1233 else:
1226 else:
1234 self.handler((etype, evalue, etb))
1227 self.handler((etype, evalue, etb))
1235 try:
1228 try:
1236 self.debugger()
1229 self.debugger()
1237 except KeyboardInterrupt:
1230 except KeyboardInterrupt:
1238 print("\nKeyboardInterrupt")
1231 print("\nKeyboardInterrupt")
1239
1232
1240
1233
1241 #----------------------------------------------------------------------------
1234 #----------------------------------------------------------------------------
1242 class FormattedTB(VerboseTB, ListTB):
1235 class FormattedTB(VerboseTB, ListTB):
1243 """Subclass ListTB but allow calling with a traceback.
1236 """Subclass ListTB but allow calling with a traceback.
1244
1237
1245 It can thus be used as a sys.excepthook for Python > 2.1.
1238 It can thus be used as a sys.excepthook for Python > 2.1.
1246
1239
1247 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1240 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1248
1241
1249 Allows a tb_offset to be specified. This is useful for situations where
1242 Allows a tb_offset to be specified. This is useful for situations where
1250 one needs to remove a number of topmost frames from the traceback (such as
1243 one needs to remove a number of topmost frames from the traceback (such as
1251 occurs with python programs that themselves execute other python code,
1244 occurs with python programs that themselves execute other python code,
1252 like Python shells). """
1245 like Python shells). """
1253
1246
1254 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1247 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1255 ostream=None,
1248 ostream=None,
1256 tb_offset=0, long_header=False, include_vars=False,
1249 tb_offset=0, long_header=False, include_vars=False,
1257 check_cache=None, debugger_cls=None,
1250 check_cache=None, debugger_cls=None,
1258 parent=None, config=None):
1251 parent=None, config=None):
1259
1252
1260 # NEVER change the order of this list. Put new modes at the end:
1253 # NEVER change the order of this list. Put new modes at the end:
1261 self.valid_modes = ['Plain', 'Context', 'Verbose']
1254 self.valid_modes = ['Plain', 'Context', 'Verbose']
1262 self.verbose_modes = self.valid_modes[1:3]
1255 self.verbose_modes = self.valid_modes[1:3]
1263
1256
1264 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1257 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1265 ostream=ostream, tb_offset=tb_offset,
1258 ostream=ostream, tb_offset=tb_offset,
1266 long_header=long_header, include_vars=include_vars,
1259 long_header=long_header, include_vars=include_vars,
1267 check_cache=check_cache, debugger_cls=debugger_cls,
1260 check_cache=check_cache, debugger_cls=debugger_cls,
1268 parent=parent, config=config)
1261 parent=parent, config=config)
1269
1262
1270 # Different types of tracebacks are joined with different separators to
1263 # Different types of tracebacks are joined with different separators to
1271 # form a single string. They are taken from this dict
1264 # form a single string. They are taken from this dict
1272 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1265 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1273 # set_mode also sets the tb_join_char attribute
1266 # set_mode also sets the tb_join_char attribute
1274 self.set_mode(mode)
1267 self.set_mode(mode)
1275
1268
1276 def _extract_tb(self, tb):
1269 def _extract_tb(self, tb):
1277 if tb:
1270 if tb:
1278 return traceback.extract_tb(tb)
1271 return traceback.extract_tb(tb)
1279 else:
1272 else:
1280 return None
1273 return None
1281
1274
1282 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1275 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1283 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1276 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1284 mode = self.mode
1277 mode = self.mode
1285 if mode in self.verbose_modes:
1278 if mode in self.verbose_modes:
1286 # Verbose modes need a full traceback
1279 # Verbose modes need a full traceback
1287 return VerboseTB.structured_traceback(
1280 return VerboseTB.structured_traceback(
1288 self, etype, value, tb, tb_offset, number_of_lines_of_context
1281 self, etype, value, tb, tb_offset, number_of_lines_of_context
1289 )
1282 )
1290 else:
1283 else:
1291 # We must check the source cache because otherwise we can print
1284 # We must check the source cache because otherwise we can print
1292 # out-of-date source code.
1285 # out-of-date source code.
1293 self.check_cache()
1286 self.check_cache()
1294 # Now we can extract and format the exception
1287 # Now we can extract and format the exception
1295 elist = self._extract_tb(tb)
1288 elist = self._extract_tb(tb)
1296 return ListTB.structured_traceback(
1289 return ListTB.structured_traceback(
1297 self, etype, value, elist, tb_offset, number_of_lines_of_context
1290 self, etype, value, elist, tb_offset, number_of_lines_of_context
1298 )
1291 )
1299
1292
1300 def stb2text(self, stb):
1293 def stb2text(self, stb):
1301 """Convert a structured traceback (a list) to a string."""
1294 """Convert a structured traceback (a list) to a string."""
1302 return self.tb_join_char.join(stb)
1295 return self.tb_join_char.join(stb)
1303
1296
1304
1297
1305 def set_mode(self, mode=None):
1298 def set_mode(self, mode=None):
1306 """Switch to the desired mode.
1299 """Switch to the desired mode.
1307
1300
1308 If mode is not specified, cycles through the available modes."""
1301 If mode is not specified, cycles through the available modes."""
1309
1302
1310 if not mode:
1303 if not mode:
1311 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1304 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1312 len(self.valid_modes)
1305 len(self.valid_modes)
1313 self.mode = self.valid_modes[new_idx]
1306 self.mode = self.valid_modes[new_idx]
1314 elif mode not in self.valid_modes:
1307 elif mode not in self.valid_modes:
1315 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1308 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1316 'Valid modes: ' + str(self.valid_modes))
1309 'Valid modes: ' + str(self.valid_modes))
1317 else:
1310 else:
1318 self.mode = mode
1311 self.mode = mode
1319 # include variable details only in 'Verbose' mode
1312 # include variable details only in 'Verbose' mode
1320 self.include_vars = (self.mode == self.valid_modes[2])
1313 self.include_vars = (self.mode == self.valid_modes[2])
1321 # Set the join character for generating text tracebacks
1314 # Set the join character for generating text tracebacks
1322 self.tb_join_char = self._join_chars[self.mode]
1315 self.tb_join_char = self._join_chars[self.mode]
1323
1316
1324 # some convenient shortcuts
1317 # some convenient shortcuts
1325 def plain(self):
1318 def plain(self):
1326 self.set_mode(self.valid_modes[0])
1319 self.set_mode(self.valid_modes[0])
1327
1320
1328 def context(self):
1321 def context(self):
1329 self.set_mode(self.valid_modes[1])
1322 self.set_mode(self.valid_modes[1])
1330
1323
1331 def verbose(self):
1324 def verbose(self):
1332 self.set_mode(self.valid_modes[2])
1325 self.set_mode(self.valid_modes[2])
1333
1326
1334
1327
1335 #----------------------------------------------------------------------------
1328 #----------------------------------------------------------------------------
1336 class AutoFormattedTB(FormattedTB):
1329 class AutoFormattedTB(FormattedTB):
1337 """A traceback printer which can be called on the fly.
1330 """A traceback printer which can be called on the fly.
1338
1331
1339 It will find out about exceptions by itself.
1332 It will find out about exceptions by itself.
1340
1333
1341 A brief example::
1334 A brief example::
1342
1335
1343 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1336 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1344 try:
1337 try:
1345 ...
1338 ...
1346 except:
1339 except:
1347 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1340 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1348 """
1341 """
1349
1342
1350 def __call__(self, etype=None, evalue=None, etb=None,
1343 def __call__(self, etype=None, evalue=None, etb=None,
1351 out=None, tb_offset=None):
1344 out=None, tb_offset=None):
1352 """Print out a formatted exception traceback.
1345 """Print out a formatted exception traceback.
1353
1346
1354 Optional arguments:
1347 Optional arguments:
1355 - out: an open file-like object to direct output to.
1348 - out: an open file-like object to direct output to.
1356
1349
1357 - tb_offset: the number of frames to skip over in the stack, on a
1350 - tb_offset: the number of frames to skip over in the stack, on a
1358 per-call basis (this overrides temporarily the instance's tb_offset
1351 per-call basis (this overrides temporarily the instance's tb_offset
1359 given at initialization time. """
1352 given at initialization time. """
1360
1353
1361 if out is None:
1354 if out is None:
1362 out = self.ostream
1355 out = self.ostream
1363 out.flush()
1356 out.flush()
1364 out.write(self.text(etype, evalue, etb, tb_offset))
1357 out.write(self.text(etype, evalue, etb, tb_offset))
1365 out.write('\n')
1358 out.write('\n')
1366 out.flush()
1359 out.flush()
1367 # FIXME: we should remove the auto pdb behavior from here and leave
1360 # FIXME: we should remove the auto pdb behavior from here and leave
1368 # that to the clients.
1361 # that to the clients.
1369 try:
1362 try:
1370 self.debugger()
1363 self.debugger()
1371 except KeyboardInterrupt:
1364 except KeyboardInterrupt:
1372 print("\nKeyboardInterrupt")
1365 print("\nKeyboardInterrupt")
1373
1366
1374 def structured_traceback(self, etype=None, value=None, tb=None,
1367 def structured_traceback(self, etype=None, value=None, tb=None,
1375 tb_offset=None, number_of_lines_of_context=5):
1368 tb_offset=None, number_of_lines_of_context=5):
1376 if etype is None:
1369 if etype is None:
1377 etype, value, tb = sys.exc_info()
1370 etype, value, tb = sys.exc_info()
1378 self.tb = tb
1371 self.tb = tb
1379 return FormattedTB.structured_traceback(
1372 return FormattedTB.structured_traceback(
1380 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1373 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1381
1374
1382
1375
1383 #---------------------------------------------------------------------------
1376 #---------------------------------------------------------------------------
1384
1377
1385 # A simple class to preserve Nathan's original functionality.
1378 # A simple class to preserve Nathan's original functionality.
1386 class ColorTB(FormattedTB):
1379 class ColorTB(FormattedTB):
1387 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1380 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1388
1381
1389 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1382 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1390 FormattedTB.__init__(self, color_scheme=color_scheme,
1383 FormattedTB.__init__(self, color_scheme=color_scheme,
1391 call_pdb=call_pdb, **kwargs)
1384 call_pdb=call_pdb, **kwargs)
1392
1385
1393
1386
1394 class SyntaxTB(ListTB):
1387 class SyntaxTB(ListTB):
1395 """Extension which holds some state: the last exception value"""
1388 """Extension which holds some state: the last exception value"""
1396
1389
1397 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1390 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1398 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1391 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1399 self.last_syntax_error = None
1392 self.last_syntax_error = None
1400
1393
1401 def __call__(self, etype, value, elist):
1394 def __call__(self, etype, value, elist):
1402 self.last_syntax_error = value
1395 self.last_syntax_error = value
1403
1396
1404 ListTB.__call__(self, etype, value, elist)
1397 ListTB.__call__(self, etype, value, elist)
1405
1398
1406 def structured_traceback(self, etype, value, elist, tb_offset=None,
1399 def structured_traceback(self, etype, value, elist, tb_offset=None,
1407 context=5):
1400 context=5):
1408 # If the source file has been edited, the line in the syntax error can
1401 # If the source file has been edited, the line in the syntax error can
1409 # be wrong (retrieved from an outdated cache). This replaces it with
1402 # be wrong (retrieved from an outdated cache). This replaces it with
1410 # the current value.
1403 # the current value.
1411 if isinstance(value, SyntaxError) \
1404 if isinstance(value, SyntaxError) \
1412 and isinstance(value.filename, str) \
1405 and isinstance(value.filename, str) \
1413 and isinstance(value.lineno, int):
1406 and isinstance(value.lineno, int):
1414 linecache.checkcache(value.filename)
1407 linecache.checkcache(value.filename)
1415 newtext = linecache.getline(value.filename, value.lineno)
1408 newtext = linecache.getline(value.filename, value.lineno)
1416 if newtext:
1409 if newtext:
1417 value.text = newtext
1410 value.text = newtext
1418 self.last_syntax_error = value
1411 self.last_syntax_error = value
1419 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1412 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1420 tb_offset=tb_offset, context=context)
1413 tb_offset=tb_offset, context=context)
1421
1414
1422 def clear_err_state(self):
1415 def clear_err_state(self):
1423 """Return the current error state and clear it"""
1416 """Return the current error state and clear it"""
1424 e = self.last_syntax_error
1417 e = self.last_syntax_error
1425 self.last_syntax_error = None
1418 self.last_syntax_error = None
1426 return e
1419 return e
1427
1420
1428 def stb2text(self, stb):
1421 def stb2text(self, stb):
1429 """Convert a structured traceback (a list) to a string."""
1422 """Convert a structured traceback (a list) to a string."""
1430 return ''.join(stb)
1423 return ''.join(stb)
1431
1424
1432
1425
1433 # some internal-use functions
1426 # some internal-use functions
1434 def text_repr(value):
1427 def text_repr(value):
1435 """Hopefully pretty robust repr equivalent."""
1428 """Hopefully pretty robust repr equivalent."""
1436 # this is pretty horrible but should always return *something*
1429 # this is pretty horrible but should always return *something*
1437 try:
1430 try:
1438 return pydoc.text.repr(value)
1431 return pydoc.text.repr(value)
1439 except KeyboardInterrupt:
1432 except KeyboardInterrupt:
1440 raise
1433 raise
1441 except:
1434 except:
1442 try:
1435 try:
1443 return repr(value)
1436 return repr(value)
1444 except KeyboardInterrupt:
1437 except KeyboardInterrupt:
1445 raise
1438 raise
1446 except:
1439 except:
1447 try:
1440 try:
1448 # all still in an except block so we catch
1441 # all still in an except block so we catch
1449 # getattr raising
1442 # getattr raising
1450 name = getattr(value, '__name__', None)
1443 name = getattr(value, '__name__', None)
1451 if name:
1444 if name:
1452 # ick, recursion
1445 # ick, recursion
1453 return text_repr(name)
1446 return text_repr(name)
1454 klass = getattr(value, '__class__', None)
1447 klass = getattr(value, '__class__', None)
1455 if klass:
1448 if klass:
1456 return '%s instance' % text_repr(klass)
1449 return '%s instance' % text_repr(klass)
1457 except KeyboardInterrupt:
1450 except KeyboardInterrupt:
1458 raise
1451 raise
1459 except:
1452 except:
1460 return 'UNRECOVERABLE REPR FAILURE'
1453 return 'UNRECOVERABLE REPR FAILURE'
1461
1454
1462
1455
1463 def eqrepr(value, repr=text_repr):
1456 def eqrepr(value, repr=text_repr):
1464 return '=%s' % repr(value)
1457 return '=%s' % repr(value)
1465
1458
1466
1459
1467 def nullrepr(value, repr=text_repr):
1460 def nullrepr(value, repr=text_repr):
1468 return ''
1461 return ''
@@ -1,108 +1,106 b''
1 """prompt-toolkit utilities
1 """prompt-toolkit utilities
2
2
3 Everything in this module is a private API,
3 Everything in this module is a private API,
4 not to be used outside IPython.
4 not to be used outside IPython.
5 """
5 """
6
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 import unicodedata
10 import unicodedata
11 from wcwidth import wcwidth
11 from wcwidth import wcwidth
12
12
13 from IPython.utils.py3compat import PY3
14
15 from IPython.core.completer import IPCompleter
13 from IPython.core.completer import IPCompleter
16 from prompt_toolkit.completion import Completer, Completion
14 from prompt_toolkit.completion import Completer, Completion
17 from prompt_toolkit.layout.lexers import Lexer
15 from prompt_toolkit.layout.lexers import Lexer
18 from prompt_toolkit.layout.lexers import PygmentsLexer
16 from prompt_toolkit.layout.lexers import PygmentsLexer
19
17
20 import pygments.lexers as pygments_lexers
18 import pygments.lexers as pygments_lexers
21
19
22
20
23 class IPythonPTCompleter(Completer):
21 class IPythonPTCompleter(Completer):
24 """Adaptor to provide IPython completions to prompt_toolkit"""
22 """Adaptor to provide IPython completions to prompt_toolkit"""
25 def __init__(self, ipy_completer=None, shell=None):
23 def __init__(self, ipy_completer=None, shell=None):
26 if shell is None and ipy_completer is None:
24 if shell is None and ipy_completer is None:
27 raise TypeError("Please pass shell=an InteractiveShell instance.")
25 raise TypeError("Please pass shell=an InteractiveShell instance.")
28 self._ipy_completer = ipy_completer
26 self._ipy_completer = ipy_completer
29 self.shell = shell
27 self.shell = shell
30
28
31 @property
29 @property
32 def ipy_completer(self):
30 def ipy_completer(self):
33 if self._ipy_completer:
31 if self._ipy_completer:
34 return self._ipy_completer
32 return self._ipy_completer
35 else:
33 else:
36 return self.shell.Completer
34 return self.shell.Completer
37
35
38 def get_completions(self, document, complete_event):
36 def get_completions(self, document, complete_event):
39 if not document.current_line.strip():
37 if not document.current_line.strip():
40 return
38 return
41
39
42 used, matches = self.ipy_completer.complete(
40 used, matches = self.ipy_completer.complete(
43 line_buffer=document.current_line,
41 line_buffer=document.current_line,
44 cursor_pos=document.cursor_position_col
42 cursor_pos=document.cursor_position_col
45 )
43 )
46 start_pos = -len(used)
44 start_pos = -len(used)
47 for m in matches:
45 for m in matches:
48 if not m:
46 if not m:
49 # Guard against completion machinery giving us an empty string.
47 # Guard against completion machinery giving us an empty string.
50 continue
48 continue
51
49
52 m = unicodedata.normalize('NFC', m)
50 m = unicodedata.normalize('NFC', m)
53
51
54 # When the first character of the completion has a zero length,
52 # When the first character of the completion has a zero length,
55 # then it's probably a decomposed unicode character. E.g. caused by
53 # then it's probably a decomposed unicode character. E.g. caused by
56 # the "\dot" completion. Try to compose again with the previous
54 # the "\dot" completion. Try to compose again with the previous
57 # character.
55 # character.
58 if wcwidth(m[0]) == 0:
56 if wcwidth(m[0]) == 0:
59 if document.cursor_position + start_pos > 0:
57 if document.cursor_position + start_pos > 0:
60 char_before = document.text[document.cursor_position + start_pos - 1]
58 char_before = document.text[document.cursor_position + start_pos - 1]
61 m = unicodedata.normalize('NFC', char_before + m)
59 m = unicodedata.normalize('NFC', char_before + m)
62
60
63 # Yield the modified completion instead, if this worked.
61 # Yield the modified completion instead, if this worked.
64 if wcwidth(m[0:1]) == 1:
62 if wcwidth(m[0:1]) == 1:
65 yield Completion(m, start_position=start_pos - 1)
63 yield Completion(m, start_position=start_pos - 1)
66 continue
64 continue
67
65
68 # TODO: Use Jedi to determine meta_text
66 # TODO: Use Jedi to determine meta_text
69 # (Jedi currently has a bug that results in incorrect information.)
67 # (Jedi currently has a bug that results in incorrect information.)
70 # meta_text = ''
68 # meta_text = ''
71 # yield Completion(m, start_position=start_pos,
69 # yield Completion(m, start_position=start_pos,
72 # display_meta=meta_text)
70 # display_meta=meta_text)
73 yield Completion(m, start_position=start_pos)
71 yield Completion(m, start_position=start_pos)
74
72
75 class IPythonPTLexer(Lexer):
73 class IPythonPTLexer(Lexer):
76 """
74 """
77 Wrapper around PythonLexer and BashLexer.
75 Wrapper around PythonLexer and BashLexer.
78 """
76 """
79 def __init__(self):
77 def __init__(self):
80 l = pygments_lexers
78 l = pygments_lexers
81 self.python_lexer = PygmentsLexer(l.Python3Lexer if PY3 else l.PythonLexer)
79 self.python_lexer = PygmentsLexer(l.Python3Lexer)
82 self.shell_lexer = PygmentsLexer(l.BashLexer)
80 self.shell_lexer = PygmentsLexer(l.BashLexer)
83
81
84 self.magic_lexers = {
82 self.magic_lexers = {
85 'HTML': PygmentsLexer(l.HtmlLexer),
83 'HTML': PygmentsLexer(l.HtmlLexer),
86 'html': PygmentsLexer(l.HtmlLexer),
84 'html': PygmentsLexer(l.HtmlLexer),
87 'javascript': PygmentsLexer(l.JavascriptLexer),
85 'javascript': PygmentsLexer(l.JavascriptLexer),
88 'js': PygmentsLexer(l.JavascriptLexer),
86 'js': PygmentsLexer(l.JavascriptLexer),
89 'perl': PygmentsLexer(l.PerlLexer),
87 'perl': PygmentsLexer(l.PerlLexer),
90 'ruby': PygmentsLexer(l.RubyLexer),
88 'ruby': PygmentsLexer(l.RubyLexer),
91 'latex': PygmentsLexer(l.TexLexer),
89 'latex': PygmentsLexer(l.TexLexer),
92 }
90 }
93
91
94 def lex_document(self, cli, document):
92 def lex_document(self, cli, document):
95 text = document.text.lstrip()
93 text = document.text.lstrip()
96
94
97 lexer = self.python_lexer
95 lexer = self.python_lexer
98
96
99 if text.startswith('!') or text.startswith('%%bash'):
97 if text.startswith('!') or text.startswith('%%bash'):
100 lexer = self.shell_lexer
98 lexer = self.shell_lexer
101
99
102 elif text.startswith('%%'):
100 elif text.startswith('%%'):
103 for magic, l in self.magic_lexers.items():
101 for magic, l in self.magic_lexers.items():
104 if text.startswith('%%' + magic):
102 if text.startswith('%%' + magic):
105 lexer = l
103 lexer = l
106 break
104 break
107
105
108 return lexer.lex_document(cli, document)
106 return lexer.lex_document(cli, document)
@@ -1,324 +1,318 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Class and program to colorize python source code for ANSI terminals.
3 Class and program to colorize python source code for ANSI terminals.
4
4
5 Based on an HTML code highlighter by Jurgen Hermann found at:
5 Based on an HTML code highlighter by Jurgen Hermann found at:
6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
7
7
8 Modifications by Fernando Perez (fperez@colorado.edu).
8 Modifications by Fernando Perez (fperez@colorado.edu).
9
9
10 Information on the original HTML highlighter follows:
10 Information on the original HTML highlighter follows:
11
11
12 MoinMoin - Python Source Parser
12 MoinMoin - Python Source Parser
13
13
14 Title: Colorize Python source using the built-in tokenizer
14 Title: Colorize Python source using the built-in tokenizer
15
15
16 Submitter: Jurgen Hermann
16 Submitter: Jurgen Hermann
17 Last Updated:2001/04/06
17 Last Updated:2001/04/06
18
18
19 Version no:1.2
19 Version no:1.2
20
20
21 Description:
21 Description:
22
22
23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
24 Python source code to HTML markup, rendering comments, keywords,
24 Python source code to HTML markup, rendering comments, keywords,
25 operators, numeric and string literals in different colors.
25 operators, numeric and string literals in different colors.
26
26
27 It shows how to use the built-in keyword, token and tokenize modules to
27 It shows how to use the built-in keyword, token and tokenize modules to
28 scan Python source code and re-emit it with no changes to its original
28 scan Python source code and re-emit it with no changes to its original
29 formatting (which is the hard part).
29 formatting (which is the hard part).
30 """
30 """
31
31
32 __all__ = ['ANSICodeColors','Parser']
32 __all__ = ['ANSICodeColors','Parser']
33
33
34 _scheme_default = 'Linux'
34 _scheme_default = 'Linux'
35
35
36
36
37 # Imports
37 # Imports
38 import keyword
38 import keyword
39 import os
39 import os
40 import sys
40 import sys
41 import token
41 import token
42 import tokenize
42 import tokenize
43
43
44 generate_tokens = tokenize.generate_tokens
44 generate_tokens = tokenize.generate_tokens
45
45
46 from IPython.utils.coloransi import TermColors, InputTermColors ,ColorScheme, ColorSchemeTable
46 from IPython.utils.coloransi import TermColors, InputTermColors ,ColorScheme, ColorSchemeTable
47 from IPython.utils.py3compat import PY3
48
49 from .colorable import Colorable
47 from .colorable import Colorable
50
51 if PY3:
52 from io import StringIO
48 from io import StringIO
53 else:
54 from StringIO import StringIO
55
49
56 #############################################################################
50 #############################################################################
57 ### Python Source Parser (does Highlighting)
51 ### Python Source Parser (does Highlighting)
58 #############################################################################
52 #############################################################################
59
53
60 _KEYWORD = token.NT_OFFSET + 1
54 _KEYWORD = token.NT_OFFSET + 1
61 _TEXT = token.NT_OFFSET + 2
55 _TEXT = token.NT_OFFSET + 2
62
56
63 #****************************************************************************
57 #****************************************************************************
64 # Builtin color schemes
58 # Builtin color schemes
65
59
66 Colors = TermColors # just a shorthand
60 Colors = TermColors # just a shorthand
67
61
68 # Build a few color schemes
62 # Build a few color schemes
69 NoColor = ColorScheme(
63 NoColor = ColorScheme(
70 'NoColor',{
64 'NoColor',{
71 'header' : Colors.NoColor,
65 'header' : Colors.NoColor,
72 token.NUMBER : Colors.NoColor,
66 token.NUMBER : Colors.NoColor,
73 token.OP : Colors.NoColor,
67 token.OP : Colors.NoColor,
74 token.STRING : Colors.NoColor,
68 token.STRING : Colors.NoColor,
75 tokenize.COMMENT : Colors.NoColor,
69 tokenize.COMMENT : Colors.NoColor,
76 token.NAME : Colors.NoColor,
70 token.NAME : Colors.NoColor,
77 token.ERRORTOKEN : Colors.NoColor,
71 token.ERRORTOKEN : Colors.NoColor,
78
72
79 _KEYWORD : Colors.NoColor,
73 _KEYWORD : Colors.NoColor,
80 _TEXT : Colors.NoColor,
74 _TEXT : Colors.NoColor,
81
75
82 'in_prompt' : InputTermColors.NoColor, # Input prompt
76 'in_prompt' : InputTermColors.NoColor, # Input prompt
83 'in_number' : InputTermColors.NoColor, # Input prompt number
77 'in_number' : InputTermColors.NoColor, # Input prompt number
84 'in_prompt2' : InputTermColors.NoColor, # Continuation prompt
78 'in_prompt2' : InputTermColors.NoColor, # Continuation prompt
85 'in_normal' : InputTermColors.NoColor, # color off (usu. Colors.Normal)
79 'in_normal' : InputTermColors.NoColor, # color off (usu. Colors.Normal)
86
80
87 'out_prompt' : Colors.NoColor, # Output prompt
81 'out_prompt' : Colors.NoColor, # Output prompt
88 'out_number' : Colors.NoColor, # Output prompt number
82 'out_number' : Colors.NoColor, # Output prompt number
89
83
90 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
84 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
91 } )
85 } )
92
86
93 LinuxColors = ColorScheme(
87 LinuxColors = ColorScheme(
94 'Linux',{
88 'Linux',{
95 'header' : Colors.LightRed,
89 'header' : Colors.LightRed,
96 token.NUMBER : Colors.LightCyan,
90 token.NUMBER : Colors.LightCyan,
97 token.OP : Colors.Yellow,
91 token.OP : Colors.Yellow,
98 token.STRING : Colors.LightBlue,
92 token.STRING : Colors.LightBlue,
99 tokenize.COMMENT : Colors.LightRed,
93 tokenize.COMMENT : Colors.LightRed,
100 token.NAME : Colors.Normal,
94 token.NAME : Colors.Normal,
101 token.ERRORTOKEN : Colors.Red,
95 token.ERRORTOKEN : Colors.Red,
102
96
103 _KEYWORD : Colors.LightGreen,
97 _KEYWORD : Colors.LightGreen,
104 _TEXT : Colors.Yellow,
98 _TEXT : Colors.Yellow,
105
99
106 'in_prompt' : InputTermColors.Green,
100 'in_prompt' : InputTermColors.Green,
107 'in_number' : InputTermColors.LightGreen,
101 'in_number' : InputTermColors.LightGreen,
108 'in_prompt2' : InputTermColors.Green,
102 'in_prompt2' : InputTermColors.Green,
109 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
103 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
110
104
111 'out_prompt' : Colors.Red,
105 'out_prompt' : Colors.Red,
112 'out_number' : Colors.LightRed,
106 'out_number' : Colors.LightRed,
113
107
114 'normal' : Colors.Normal # color off (usu. Colors.Normal)
108 'normal' : Colors.Normal # color off (usu. Colors.Normal)
115 } )
109 } )
116
110
117 NeutralColors = ColorScheme(
111 NeutralColors = ColorScheme(
118 'Neutral',{
112 'Neutral',{
119 'header' : Colors.Red,
113 'header' : Colors.Red,
120 token.NUMBER : Colors.Cyan,
114 token.NUMBER : Colors.Cyan,
121 token.OP : Colors.Blue,
115 token.OP : Colors.Blue,
122 token.STRING : Colors.Blue,
116 token.STRING : Colors.Blue,
123 tokenize.COMMENT : Colors.Red,
117 tokenize.COMMENT : Colors.Red,
124 token.NAME : Colors.Normal,
118 token.NAME : Colors.Normal,
125 token.ERRORTOKEN : Colors.Red,
119 token.ERRORTOKEN : Colors.Red,
126
120
127 _KEYWORD : Colors.Green,
121 _KEYWORD : Colors.Green,
128 _TEXT : Colors.Blue,
122 _TEXT : Colors.Blue,
129
123
130 'in_prompt' : InputTermColors.Blue,
124 'in_prompt' : InputTermColors.Blue,
131 'in_number' : InputTermColors.LightBlue,
125 'in_number' : InputTermColors.LightBlue,
132 'in_prompt2' : InputTermColors.Blue,
126 'in_prompt2' : InputTermColors.Blue,
133 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
127 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
134
128
135 'out_prompt' : Colors.Red,
129 'out_prompt' : Colors.Red,
136 'out_number' : Colors.LightRed,
130 'out_number' : Colors.LightRed,
137
131
138 'normal' : Colors.Normal # color off (usu. Colors.Normal)
132 'normal' : Colors.Normal # color off (usu. Colors.Normal)
139 } )
133 } )
140
134
141 # Hack: the 'neutral' colours are not very visible on a dark background on
135 # Hack: the 'neutral' colours are not very visible on a dark background on
142 # Windows. Since Windows command prompts have a dark background by default, and
136 # Windows. Since Windows command prompts have a dark background by default, and
143 # relatively few users are likely to alter that, we will use the 'Linux' colours,
137 # relatively few users are likely to alter that, we will use the 'Linux' colours,
144 # designed for a dark background, as the default on Windows. Changing it here
138 # designed for a dark background, as the default on Windows. Changing it here
145 # avoids affecting the prompt colours rendered by prompt_toolkit, where the
139 # avoids affecting the prompt colours rendered by prompt_toolkit, where the
146 # neutral defaults do work OK.
140 # neutral defaults do work OK.
147
141
148 if os.name == 'nt':
142 if os.name == 'nt':
149 NeutralColors = LinuxColors.copy(name='Neutral')
143 NeutralColors = LinuxColors.copy(name='Neutral')
150
144
151 LightBGColors = ColorScheme(
145 LightBGColors = ColorScheme(
152 'LightBG',{
146 'LightBG',{
153 'header' : Colors.Red,
147 'header' : Colors.Red,
154 token.NUMBER : Colors.Cyan,
148 token.NUMBER : Colors.Cyan,
155 token.OP : Colors.Blue,
149 token.OP : Colors.Blue,
156 token.STRING : Colors.Blue,
150 token.STRING : Colors.Blue,
157 tokenize.COMMENT : Colors.Red,
151 tokenize.COMMENT : Colors.Red,
158 token.NAME : Colors.Normal,
152 token.NAME : Colors.Normal,
159 token.ERRORTOKEN : Colors.Red,
153 token.ERRORTOKEN : Colors.Red,
160
154
161
155
162 _KEYWORD : Colors.Green,
156 _KEYWORD : Colors.Green,
163 _TEXT : Colors.Blue,
157 _TEXT : Colors.Blue,
164
158
165 'in_prompt' : InputTermColors.Blue,
159 'in_prompt' : InputTermColors.Blue,
166 'in_number' : InputTermColors.LightBlue,
160 'in_number' : InputTermColors.LightBlue,
167 'in_prompt2' : InputTermColors.Blue,
161 'in_prompt2' : InputTermColors.Blue,
168 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
162 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
169
163
170 'out_prompt' : Colors.Red,
164 'out_prompt' : Colors.Red,
171 'out_number' : Colors.LightRed,
165 'out_number' : Colors.LightRed,
172
166
173 'normal' : Colors.Normal # color off (usu. Colors.Normal)
167 'normal' : Colors.Normal # color off (usu. Colors.Normal)
174 } )
168 } )
175
169
176 # Build table of color schemes (needed by the parser)
170 # Build table of color schemes (needed by the parser)
177 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors, NeutralColors],
171 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors, NeutralColors],
178 _scheme_default)
172 _scheme_default)
179
173
180 Undefined = object()
174 Undefined = object()
181
175
182 class Parser(Colorable):
176 class Parser(Colorable):
183 """ Format colored Python source.
177 """ Format colored Python source.
184 """
178 """
185
179
186 def __init__(self, color_table=None, out = sys.stdout, parent=None, style=None):
180 def __init__(self, color_table=None, out = sys.stdout, parent=None, style=None):
187 """ Create a parser with a specified color table and output channel.
181 """ Create a parser with a specified color table and output channel.
188
182
189 Call format() to process code.
183 Call format() to process code.
190 """
184 """
191
185
192 super(Parser, self).__init__(parent=parent)
186 super(Parser, self).__init__(parent=parent)
193
187
194 self.color_table = color_table and color_table or ANSICodeColors
188 self.color_table = color_table and color_table or ANSICodeColors
195 self.out = out
189 self.out = out
196 if not style:
190 if not style:
197 self.style = self.default_style
191 self.style = self.default_style
198 else:
192 else:
199 self.style = style
193 self.style = style
200
194
201
195
202 def format(self, raw, out=None, scheme=Undefined):
196 def format(self, raw, out=None, scheme=Undefined):
203 import warnings
197 import warnings
204 if scheme is not Undefined:
198 if scheme is not Undefined:
205 warnings.warn('The `scheme` argument of IPython.utils.PyColorize:Parser.format is deprecated since IPython 6.0.'
199 warnings.warn('The `scheme` argument of IPython.utils.PyColorize:Parser.format is deprecated since IPython 6.0.'
206 'It will have no effect. Set the parser `style` directly.',
200 'It will have no effect. Set the parser `style` directly.',
207 stacklevel=2)
201 stacklevel=2)
208 return self.format2(raw, out)[0]
202 return self.format2(raw, out)[0]
209
203
210 def format2(self, raw, out = None):
204 def format2(self, raw, out = None):
211 """ Parse and send the colored source.
205 """ Parse and send the colored source.
212
206
213 If out and scheme are not specified, the defaults (given to
207 If out and scheme are not specified, the defaults (given to
214 constructor) are used.
208 constructor) are used.
215
209
216 out should be a file-type object. Optionally, out can be given as the
210 out should be a file-type object. Optionally, out can be given as the
217 string 'str' and the parser will automatically return the output in a
211 string 'str' and the parser will automatically return the output in a
218 string."""
212 string."""
219
213
220 string_output = 0
214 string_output = 0
221 if out == 'str' or self.out == 'str' or \
215 if out == 'str' or self.out == 'str' or \
222 isinstance(self.out,StringIO):
216 isinstance(self.out,StringIO):
223 # XXX - I don't really like this state handling logic, but at this
217 # XXX - I don't really like this state handling logic, but at this
224 # point I don't want to make major changes, so adding the
218 # point I don't want to make major changes, so adding the
225 # isinstance() check is the simplest I can do to ensure correct
219 # isinstance() check is the simplest I can do to ensure correct
226 # behavior.
220 # behavior.
227 out_old = self.out
221 out_old = self.out
228 self.out = StringIO()
222 self.out = StringIO()
229 string_output = 1
223 string_output = 1
230 elif out is not None:
224 elif out is not None:
231 self.out = out
225 self.out = out
232
226
233 # Fast return of the unmodified input for NoColor scheme
227 # Fast return of the unmodified input for NoColor scheme
234 if self.style == 'NoColor':
228 if self.style == 'NoColor':
235 error = False
229 error = False
236 self.out.write(raw)
230 self.out.write(raw)
237 if string_output:
231 if string_output:
238 return raw,error
232 return raw,error
239 else:
233 else:
240 return None,error
234 return None,error
241
235
242 # local shorthands
236 # local shorthands
243 colors = self.color_table[self.style].colors
237 colors = self.color_table[self.style].colors
244 self.colors = colors # put in object so __call__ sees it
238 self.colors = colors # put in object so __call__ sees it
245
239
246 # Remove trailing whitespace and normalize tabs
240 # Remove trailing whitespace and normalize tabs
247 self.raw = raw.expandtabs().rstrip()
241 self.raw = raw.expandtabs().rstrip()
248
242
249 # store line offsets in self.lines
243 # store line offsets in self.lines
250 self.lines = [0, 0]
244 self.lines = [0, 0]
251 pos = 0
245 pos = 0
252 raw_find = self.raw.find
246 raw_find = self.raw.find
253 lines_append = self.lines.append
247 lines_append = self.lines.append
254 while 1:
248 while 1:
255 pos = raw_find('\n', pos) + 1
249 pos = raw_find('\n', pos) + 1
256 if not pos: break
250 if not pos: break
257 lines_append(pos)
251 lines_append(pos)
258 lines_append(len(self.raw))
252 lines_append(len(self.raw))
259
253
260 # parse the source and write it
254 # parse the source and write it
261 self.pos = 0
255 self.pos = 0
262 text = StringIO(self.raw)
256 text = StringIO(self.raw)
263
257
264 error = False
258 error = False
265 try:
259 try:
266 for atoken in generate_tokens(text.readline):
260 for atoken in generate_tokens(text.readline):
267 self(*atoken)
261 self(*atoken)
268 except tokenize.TokenError as ex:
262 except tokenize.TokenError as ex:
269 msg = ex.args[0]
263 msg = ex.args[0]
270 line = ex.args[1][0]
264 line = ex.args[1][0]
271 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
265 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
272 (colors[token.ERRORTOKEN],
266 (colors[token.ERRORTOKEN],
273 msg, self.raw[self.lines[line]:],
267 msg, self.raw[self.lines[line]:],
274 colors.normal)
268 colors.normal)
275 )
269 )
276 error = True
270 error = True
277 self.out.write(colors.normal+'\n')
271 self.out.write(colors.normal+'\n')
278 if string_output:
272 if string_output:
279 output = self.out.getvalue()
273 output = self.out.getvalue()
280 self.out = out_old
274 self.out = out_old
281 return (output, error)
275 return (output, error)
282 return (None, error)
276 return (None, error)
283
277
284 def __call__(self, toktype, toktext, start_pos, end_pos, line):
278 def __call__(self, toktype, toktext, start_pos, end_pos, line):
285 """ Token handler, with syntax highlighting."""
279 """ Token handler, with syntax highlighting."""
286 (srow,scol) = start_pos
280 (srow,scol) = start_pos
287 (erow,ecol) = end_pos
281 (erow,ecol) = end_pos
288 colors = self.colors
282 colors = self.colors
289 owrite = self.out.write
283 owrite = self.out.write
290
284
291 # line separator, so this works across platforms
285 # line separator, so this works across platforms
292 linesep = os.linesep
286 linesep = os.linesep
293
287
294 # calculate new positions
288 # calculate new positions
295 oldpos = self.pos
289 oldpos = self.pos
296 newpos = self.lines[srow] + scol
290 newpos = self.lines[srow] + scol
297 self.pos = newpos + len(toktext)
291 self.pos = newpos + len(toktext)
298
292
299 # send the original whitespace, if needed
293 # send the original whitespace, if needed
300 if newpos > oldpos:
294 if newpos > oldpos:
301 owrite(self.raw[oldpos:newpos])
295 owrite(self.raw[oldpos:newpos])
302
296
303 # skip indenting tokens
297 # skip indenting tokens
304 if toktype in [token.INDENT, token.DEDENT]:
298 if toktype in [token.INDENT, token.DEDENT]:
305 self.pos = newpos
299 self.pos = newpos
306 return
300 return
307
301
308 # map token type to a color group
302 # map token type to a color group
309 if token.LPAR <= toktype <= token.OP:
303 if token.LPAR <= toktype <= token.OP:
310 toktype = token.OP
304 toktype = token.OP
311 elif toktype == token.NAME and keyword.iskeyword(toktext):
305 elif toktype == token.NAME and keyword.iskeyword(toktext):
312 toktype = _KEYWORD
306 toktype = _KEYWORD
313 color = colors.get(toktype, colors[_TEXT])
307 color = colors.get(toktype, colors[_TEXT])
314
308
315 #print '<%s>' % toktext, # dbg
309 #print '<%s>' % toktext, # dbg
316
310
317 # Triple quoted strings must be handled carefully so that backtracking
311 # Triple quoted strings must be handled carefully so that backtracking
318 # in pagers works correctly. We need color terminators on _each_ line.
312 # in pagers works correctly. We need color terminators on _each_ line.
319 if linesep in toktext:
313 if linesep in toktext:
320 toktext = toktext.replace(linesep, '%s%s%s' %
314 toktext = toktext.replace(linesep, '%s%s%s' %
321 (colors.normal,linesep,color))
315 (colors.normal,linesep,color))
322
316
323 # send text
317 # send text
324 owrite('%s%s%s' % (color,toktext,colors.normal))
318 owrite('%s%s%s' % (color,toktext,colors.normal))
@@ -1,172 +1,166 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """IO capturing utilities."""
2 """IO capturing utilities."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 import sys
8 import sys
9
10 from IPython.utils.py3compat import PY3
11
12 if PY3:
13 from io import StringIO
9 from io import StringIO
14 else:
15 from StringIO import StringIO
16
10
17 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
18 # Classes and functions
12 # Classes and functions
19 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
20
14
21
15
22 class RichOutput(object):
16 class RichOutput(object):
23 def __init__(self, data=None, metadata=None):
17 def __init__(self, data=None, metadata=None):
24 self.data = data or {}
18 self.data = data or {}
25 self.metadata = metadata or {}
19 self.metadata = metadata or {}
26
20
27 def display(self):
21 def display(self):
28 from IPython.display import publish_display_data
22 from IPython.display import publish_display_data
29 publish_display_data(data=self.data, metadata=self.metadata)
23 publish_display_data(data=self.data, metadata=self.metadata)
30
24
31 def _repr_mime_(self, mime):
25 def _repr_mime_(self, mime):
32 if mime not in self.data:
26 if mime not in self.data:
33 return
27 return
34 data = self.data[mime]
28 data = self.data[mime]
35 if mime in self.metadata:
29 if mime in self.metadata:
36 return data, self.metadata[mime]
30 return data, self.metadata[mime]
37 else:
31 else:
38 return data
32 return data
39
33
40 def _repr_html_(self):
34 def _repr_html_(self):
41 return self._repr_mime_("text/html")
35 return self._repr_mime_("text/html")
42
36
43 def _repr_latex_(self):
37 def _repr_latex_(self):
44 return self._repr_mime_("text/latex")
38 return self._repr_mime_("text/latex")
45
39
46 def _repr_json_(self):
40 def _repr_json_(self):
47 return self._repr_mime_("application/json")
41 return self._repr_mime_("application/json")
48
42
49 def _repr_javascript_(self):
43 def _repr_javascript_(self):
50 return self._repr_mime_("application/javascript")
44 return self._repr_mime_("application/javascript")
51
45
52 def _repr_png_(self):
46 def _repr_png_(self):
53 return self._repr_mime_("image/png")
47 return self._repr_mime_("image/png")
54
48
55 def _repr_jpeg_(self):
49 def _repr_jpeg_(self):
56 return self._repr_mime_("image/jpeg")
50 return self._repr_mime_("image/jpeg")
57
51
58 def _repr_svg_(self):
52 def _repr_svg_(self):
59 return self._repr_mime_("image/svg+xml")
53 return self._repr_mime_("image/svg+xml")
60
54
61
55
62 class CapturedIO(object):
56 class CapturedIO(object):
63 """Simple object for containing captured stdout/err and rich display StringIO objects
57 """Simple object for containing captured stdout/err and rich display StringIO objects
64
58
65 Each instance `c` has three attributes:
59 Each instance `c` has three attributes:
66
60
67 - ``c.stdout`` : standard output as a string
61 - ``c.stdout`` : standard output as a string
68 - ``c.stderr`` : standard error as a string
62 - ``c.stderr`` : standard error as a string
69 - ``c.outputs``: a list of rich display outputs
63 - ``c.outputs``: a list of rich display outputs
70
64
71 Additionally, there's a ``c.show()`` method which will print all of the
65 Additionally, there's a ``c.show()`` method which will print all of the
72 above in the same order, and can be invoked simply via ``c()``.
66 above in the same order, and can be invoked simply via ``c()``.
73 """
67 """
74
68
75 def __init__(self, stdout, stderr, outputs=None):
69 def __init__(self, stdout, stderr, outputs=None):
76 self._stdout = stdout
70 self._stdout = stdout
77 self._stderr = stderr
71 self._stderr = stderr
78 if outputs is None:
72 if outputs is None:
79 outputs = []
73 outputs = []
80 self._outputs = outputs
74 self._outputs = outputs
81
75
82 def __str__(self):
76 def __str__(self):
83 return self.stdout
77 return self.stdout
84
78
85 @property
79 @property
86 def stdout(self):
80 def stdout(self):
87 "Captured standard output"
81 "Captured standard output"
88 if not self._stdout:
82 if not self._stdout:
89 return ''
83 return ''
90 return self._stdout.getvalue()
84 return self._stdout.getvalue()
91
85
92 @property
86 @property
93 def stderr(self):
87 def stderr(self):
94 "Captured standard error"
88 "Captured standard error"
95 if not self._stderr:
89 if not self._stderr:
96 return ''
90 return ''
97 return self._stderr.getvalue()
91 return self._stderr.getvalue()
98
92
99 @property
93 @property
100 def outputs(self):
94 def outputs(self):
101 """A list of the captured rich display outputs, if any.
95 """A list of the captured rich display outputs, if any.
102
96
103 If you have a CapturedIO object ``c``, these can be displayed in IPython
97 If you have a CapturedIO object ``c``, these can be displayed in IPython
104 using::
98 using::
105
99
106 from IPython.display import display
100 from IPython.display import display
107 for o in c.outputs:
101 for o in c.outputs:
108 display(o)
102 display(o)
109 """
103 """
110 return [ RichOutput(d, md) for d, md in self._outputs ]
104 return [ RichOutput(d, md) for d, md in self._outputs ]
111
105
112 def show(self):
106 def show(self):
113 """write my output to sys.stdout/err as appropriate"""
107 """write my output to sys.stdout/err as appropriate"""
114 sys.stdout.write(self.stdout)
108 sys.stdout.write(self.stdout)
115 sys.stderr.write(self.stderr)
109 sys.stderr.write(self.stderr)
116 sys.stdout.flush()
110 sys.stdout.flush()
117 sys.stderr.flush()
111 sys.stderr.flush()
118 for data, metadata in self._outputs:
112 for data, metadata in self._outputs:
119 RichOutput(data, metadata).display()
113 RichOutput(data, metadata).display()
120
114
121 __call__ = show
115 __call__ = show
122
116
123
117
124 class capture_output(object):
118 class capture_output(object):
125 """context manager for capturing stdout/err"""
119 """context manager for capturing stdout/err"""
126 stdout = True
120 stdout = True
127 stderr = True
121 stderr = True
128 display = True
122 display = True
129
123
130 def __init__(self, stdout=True, stderr=True, display=True):
124 def __init__(self, stdout=True, stderr=True, display=True):
131 self.stdout = stdout
125 self.stdout = stdout
132 self.stderr = stderr
126 self.stderr = stderr
133 self.display = display
127 self.display = display
134 self.shell = None
128 self.shell = None
135
129
136 def __enter__(self):
130 def __enter__(self):
137 from IPython.core.getipython import get_ipython
131 from IPython.core.getipython import get_ipython
138 from IPython.core.displaypub import CapturingDisplayPublisher
132 from IPython.core.displaypub import CapturingDisplayPublisher
139 from IPython.core.displayhook import CapturingDisplayHook
133 from IPython.core.displayhook import CapturingDisplayHook
140
134
141 self.sys_stdout = sys.stdout
135 self.sys_stdout = sys.stdout
142 self.sys_stderr = sys.stderr
136 self.sys_stderr = sys.stderr
143
137
144 if self.display:
138 if self.display:
145 self.shell = get_ipython()
139 self.shell = get_ipython()
146 if self.shell is None:
140 if self.shell is None:
147 self.save_display_pub = None
141 self.save_display_pub = None
148 self.display = False
142 self.display = False
149
143
150 stdout = stderr = outputs = None
144 stdout = stderr = outputs = None
151 if self.stdout:
145 if self.stdout:
152 stdout = sys.stdout = StringIO()
146 stdout = sys.stdout = StringIO()
153 if self.stderr:
147 if self.stderr:
154 stderr = sys.stderr = StringIO()
148 stderr = sys.stderr = StringIO()
155 if self.display:
149 if self.display:
156 self.save_display_pub = self.shell.display_pub
150 self.save_display_pub = self.shell.display_pub
157 self.shell.display_pub = CapturingDisplayPublisher()
151 self.shell.display_pub = CapturingDisplayPublisher()
158 outputs = self.shell.display_pub.outputs
152 outputs = self.shell.display_pub.outputs
159 self.save_display_hook = sys.displayhook
153 self.save_display_hook = sys.displayhook
160 sys.displayhook = CapturingDisplayHook(shell=self.shell,
154 sys.displayhook = CapturingDisplayHook(shell=self.shell,
161 outputs=outputs)
155 outputs=outputs)
162
156
163 return CapturedIO(stdout, stderr, outputs)
157 return CapturedIO(stdout, stderr, outputs)
164
158
165 def __exit__(self, exc_type, exc_value, traceback):
159 def __exit__(self, exc_type, exc_value, traceback):
166 sys.stdout = self.sys_stdout
160 sys.stdout = self.sys_stdout
167 sys.stderr = self.sys_stderr
161 sys.stderr = self.sys_stderr
168 if self.display and self.shell:
162 if self.display and self.shell:
169 self.shell.display_pub = self.save_display_pub
163 self.shell.display_pub = self.save_display_pub
170 sys.displayhook = self.save_display_hook
164 sys.displayhook = self.save_display_hook
171
165
172
166
@@ -1,240 +1,240 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 IO related utilities.
3 IO related utilities.
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9
9
10
10
11 import atexit
11 import atexit
12 import os
12 import os
13 import sys
13 import sys
14 import tempfile
14 import tempfile
15 import warnings
15 import warnings
16 from warnings import warn
16 from warnings import warn
17
17
18 from IPython.utils.decorators import undoc
18 from IPython.utils.decorators import undoc
19 from .capture import CapturedIO, capture_output
19 from .capture import CapturedIO, capture_output
20 from .py3compat import input, PY3
20 from .py3compat import input
21
21
22 @undoc
22 @undoc
23 class IOStream:
23 class IOStream:
24
24
25 def __init__(self, stream, fallback=None):
25 def __init__(self, stream, fallback=None):
26 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
26 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
27 DeprecationWarning, stacklevel=2)
27 DeprecationWarning, stacklevel=2)
28 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
28 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
29 if fallback is not None:
29 if fallback is not None:
30 stream = fallback
30 stream = fallback
31 else:
31 else:
32 raise ValueError("fallback required, but not specified")
32 raise ValueError("fallback required, but not specified")
33 self.stream = stream
33 self.stream = stream
34 self._swrite = stream.write
34 self._swrite = stream.write
35
35
36 # clone all methods not overridden:
36 # clone all methods not overridden:
37 def clone(meth):
37 def clone(meth):
38 return not hasattr(self, meth) and not meth.startswith('_')
38 return not hasattr(self, meth) and not meth.startswith('_')
39 for meth in filter(clone, dir(stream)):
39 for meth in filter(clone, dir(stream)):
40 setattr(self, meth, getattr(stream, meth))
40 setattr(self, meth, getattr(stream, meth))
41
41
42 def __repr__(self):
42 def __repr__(self):
43 cls = self.__class__
43 cls = self.__class__
44 tpl = '{mod}.{cls}({args})'
44 tpl = '{mod}.{cls}({args})'
45 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
45 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
46
46
47 def write(self,data):
47 def write(self,data):
48 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
48 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
49 DeprecationWarning, stacklevel=2)
49 DeprecationWarning, stacklevel=2)
50 try:
50 try:
51 self._swrite(data)
51 self._swrite(data)
52 except:
52 except:
53 try:
53 try:
54 # print handles some unicode issues which may trip a plain
54 # print handles some unicode issues which may trip a plain
55 # write() call. Emulate write() by using an empty end
55 # write() call. Emulate write() by using an empty end
56 # argument.
56 # argument.
57 print(data, end='', file=self.stream)
57 print(data, end='', file=self.stream)
58 except:
58 except:
59 # if we get here, something is seriously broken.
59 # if we get here, something is seriously broken.
60 print('ERROR - failed to write data to stream:', self.stream,
60 print('ERROR - failed to write data to stream:', self.stream,
61 file=sys.stderr)
61 file=sys.stderr)
62
62
63 def writelines(self, lines):
63 def writelines(self, lines):
64 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
64 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
65 DeprecationWarning, stacklevel=2)
65 DeprecationWarning, stacklevel=2)
66 if isinstance(lines, str):
66 if isinstance(lines, str):
67 lines = [lines]
67 lines = [lines]
68 for line in lines:
68 for line in lines:
69 self.write(line)
69 self.write(line)
70
70
71 # This class used to have a writeln method, but regular files and streams
71 # This class used to have a writeln method, but regular files and streams
72 # in Python don't have this method. We need to keep this completely
72 # in Python don't have this method. We need to keep this completely
73 # compatible so we removed it.
73 # compatible so we removed it.
74
74
75 @property
75 @property
76 def closed(self):
76 def closed(self):
77 return self.stream.closed
77 return self.stream.closed
78
78
79 def close(self):
79 def close(self):
80 pass
80 pass
81
81
82 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
82 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
83 devnull = open(os.devnull, 'w')
83 devnull = open(os.devnull, 'w')
84 atexit.register(devnull.close)
84 atexit.register(devnull.close)
85
85
86 # io.std* are deprecated, but don't show our own deprecation warnings
86 # io.std* are deprecated, but don't show our own deprecation warnings
87 # during initialization of the deprecated API.
87 # during initialization of the deprecated API.
88 with warnings.catch_warnings():
88 with warnings.catch_warnings():
89 warnings.simplefilter('ignore', DeprecationWarning)
89 warnings.simplefilter('ignore', DeprecationWarning)
90 stdin = IOStream(sys.stdin, fallback=devnull)
90 stdin = IOStream(sys.stdin, fallback=devnull)
91 stdout = IOStream(sys.stdout, fallback=devnull)
91 stdout = IOStream(sys.stdout, fallback=devnull)
92 stderr = IOStream(sys.stderr, fallback=devnull)
92 stderr = IOStream(sys.stderr, fallback=devnull)
93
93
94 class Tee(object):
94 class Tee(object):
95 """A class to duplicate an output stream to stdout/err.
95 """A class to duplicate an output stream to stdout/err.
96
96
97 This works in a manner very similar to the Unix 'tee' command.
97 This works in a manner very similar to the Unix 'tee' command.
98
98
99 When the object is closed or deleted, it closes the original file given to
99 When the object is closed or deleted, it closes the original file given to
100 it for duplication.
100 it for duplication.
101 """
101 """
102 # Inspired by:
102 # Inspired by:
103 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
103 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
104
104
105 def __init__(self, file_or_name, mode="w", channel='stdout'):
105 def __init__(self, file_or_name, mode="w", channel='stdout'):
106 """Construct a new Tee object.
106 """Construct a new Tee object.
107
107
108 Parameters
108 Parameters
109 ----------
109 ----------
110 file_or_name : filename or open filehandle (writable)
110 file_or_name : filename or open filehandle (writable)
111 File that will be duplicated
111 File that will be duplicated
112
112
113 mode : optional, valid mode for open().
113 mode : optional, valid mode for open().
114 If a filename was give, open with this mode.
114 If a filename was give, open with this mode.
115
115
116 channel : str, one of ['stdout', 'stderr']
116 channel : str, one of ['stdout', 'stderr']
117 """
117 """
118 if channel not in ['stdout', 'stderr']:
118 if channel not in ['stdout', 'stderr']:
119 raise ValueError('Invalid channel spec %s' % channel)
119 raise ValueError('Invalid channel spec %s' % channel)
120
120
121 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
121 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
122 self.file = file_or_name
122 self.file = file_or_name
123 else:
123 else:
124 self.file = open(file_or_name, mode)
124 self.file = open(file_or_name, mode)
125 self.channel = channel
125 self.channel = channel
126 self.ostream = getattr(sys, channel)
126 self.ostream = getattr(sys, channel)
127 setattr(sys, channel, self)
127 setattr(sys, channel, self)
128 self._closed = False
128 self._closed = False
129
129
130 def close(self):
130 def close(self):
131 """Close the file and restore the channel."""
131 """Close the file and restore the channel."""
132 self.flush()
132 self.flush()
133 setattr(sys, self.channel, self.ostream)
133 setattr(sys, self.channel, self.ostream)
134 self.file.close()
134 self.file.close()
135 self._closed = True
135 self._closed = True
136
136
137 def write(self, data):
137 def write(self, data):
138 """Write data to both channels."""
138 """Write data to both channels."""
139 self.file.write(data)
139 self.file.write(data)
140 self.ostream.write(data)
140 self.ostream.write(data)
141 self.ostream.flush()
141 self.ostream.flush()
142
142
143 def flush(self):
143 def flush(self):
144 """Flush both channels."""
144 """Flush both channels."""
145 self.file.flush()
145 self.file.flush()
146 self.ostream.flush()
146 self.ostream.flush()
147
147
148 def __del__(self):
148 def __del__(self):
149 if not self._closed:
149 if not self._closed:
150 self.close()
150 self.close()
151
151
152
152
153 def ask_yes_no(prompt, default=None, interrupt=None):
153 def ask_yes_no(prompt, default=None, interrupt=None):
154 """Asks a question and returns a boolean (y/n) answer.
154 """Asks a question and returns a boolean (y/n) answer.
155
155
156 If default is given (one of 'y','n'), it is used if the user input is
156 If default is given (one of 'y','n'), it is used if the user input is
157 empty. If interrupt is given (one of 'y','n'), it is used if the user
157 empty. If interrupt is given (one of 'y','n'), it is used if the user
158 presses Ctrl-C. Otherwise the question is repeated until an answer is
158 presses Ctrl-C. Otherwise the question is repeated until an answer is
159 given.
159 given.
160
160
161 An EOF is treated as the default answer. If there is no default, an
161 An EOF is treated as the default answer. If there is no default, an
162 exception is raised to prevent infinite loops.
162 exception is raised to prevent infinite loops.
163
163
164 Valid answers are: y/yes/n/no (match is not case sensitive)."""
164 Valid answers are: y/yes/n/no (match is not case sensitive)."""
165
165
166 answers = {'y':True,'n':False,'yes':True,'no':False}
166 answers = {'y':True,'n':False,'yes':True,'no':False}
167 ans = None
167 ans = None
168 while ans not in answers.keys():
168 while ans not in answers.keys():
169 try:
169 try:
170 ans = input(prompt+' ').lower()
170 ans = input(prompt+' ').lower()
171 if not ans: # response was an empty string
171 if not ans: # response was an empty string
172 ans = default
172 ans = default
173 except KeyboardInterrupt:
173 except KeyboardInterrupt:
174 if interrupt:
174 if interrupt:
175 ans = interrupt
175 ans = interrupt
176 print("\r")
176 print("\r")
177 except EOFError:
177 except EOFError:
178 if default in answers.keys():
178 if default in answers.keys():
179 ans = default
179 ans = default
180 print()
180 print()
181 else:
181 else:
182 raise
182 raise
183
183
184 return answers[ans]
184 return answers[ans]
185
185
186
186
187 def temp_pyfile(src, ext='.py'):
187 def temp_pyfile(src, ext='.py'):
188 """Make a temporary python file, return filename and filehandle.
188 """Make a temporary python file, return filename and filehandle.
189
189
190 Parameters
190 Parameters
191 ----------
191 ----------
192 src : string or list of strings (no need for ending newlines if list)
192 src : string or list of strings (no need for ending newlines if list)
193 Source code to be written to the file.
193 Source code to be written to the file.
194
194
195 ext : optional, string
195 ext : optional, string
196 Extension for the generated file.
196 Extension for the generated file.
197
197
198 Returns
198 Returns
199 -------
199 -------
200 (filename, open filehandle)
200 (filename, open filehandle)
201 It is the caller's responsibility to close the open file and unlink it.
201 It is the caller's responsibility to close the open file and unlink it.
202 """
202 """
203 fname = tempfile.mkstemp(ext)[1]
203 fname = tempfile.mkstemp(ext)[1]
204 f = open(fname,'w')
204 f = open(fname,'w')
205 f.write(src)
205 f.write(src)
206 f.flush()
206 f.flush()
207 return fname, f
207 return fname, f
208
208
209 def atomic_writing(*args, **kwargs):
209 def atomic_writing(*args, **kwargs):
210 """DEPRECATED: moved to notebook.services.contents.fileio"""
210 """DEPRECATED: moved to notebook.services.contents.fileio"""
211 warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio", stacklevel=2)
211 warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio", stacklevel=2)
212 from notebook.services.contents.fileio import atomic_writing
212 from notebook.services.contents.fileio import atomic_writing
213 return atomic_writing(*args, **kwargs)
213 return atomic_writing(*args, **kwargs)
214
214
215 def raw_print(*args, **kw):
215 def raw_print(*args, **kw):
216 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
216 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
217
217
218 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
218 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
219 file=sys.__stdout__)
219 file=sys.__stdout__)
220 sys.__stdout__.flush()
220 sys.__stdout__.flush()
221
221
222
222
223 def raw_print_err(*args, **kw):
223 def raw_print_err(*args, **kw):
224 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
224 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
225
225
226 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
226 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
227 file=sys.__stderr__)
227 file=sys.__stderr__)
228 sys.__stderr__.flush()
228 sys.__stderr__.flush()
229
229
230
230
231 # Short aliases for quick debugging, do NOT use these in production code.
231 # Short aliases for quick debugging, do NOT use these in production code.
232 rprint = raw_print
232 rprint = raw_print
233 rprinte = raw_print_err
233 rprinte = raw_print_err
234
234
235
235
236 def unicode_std_stream(stream='stdout'):
236 def unicode_std_stream(stream='stdout'):
237 """DEPRECATED, moved to nbconvert.utils.io"""
237 """DEPRECATED, moved to nbconvert.utils.io"""
238 warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io", stacklevel=2)
238 warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io", stacklevel=2)
239 from nbconvert.utils.io import unicode_std_stream
239 from nbconvert.utils.io import unicode_std_stream
240 return unicode_std_stream(stream)
240 return unicode_std_stream(stream)
@@ -1,85 +1,81 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for io.py"""
2 """Tests for io.py"""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 import io as stdlib_io
8 import io as stdlib_io
9 import os.path
9 import os.path
10 import stat
10 import stat
11 import sys
11 import sys
12 from io import StringIO
12
13
13 from subprocess import Popen, PIPE
14 from subprocess import Popen, PIPE
14 import unittest
15 import unittest
15
16
16 import nose.tools as nt
17 import nose.tools as nt
17
18
18 from IPython.testing.decorators import skipif, skip_win32
19 from IPython.testing.decorators import skipif, skip_win32
19 from IPython.utils.io import Tee, capture_output
20 from IPython.utils.io import Tee, capture_output
20 from IPython.utils.py3compat import doctest_refactor_print, PY3
21 from IPython.utils.py3compat import doctest_refactor_print
21 from IPython.utils.tempdir import TemporaryDirectory
22 from IPython.utils.tempdir import TemporaryDirectory
22
23
23 if PY3:
24 from io import StringIO
25 else:
26 from StringIO import StringIO
27
28
24
29 def test_tee_simple():
25 def test_tee_simple():
30 "Very simple check with stdout only"
26 "Very simple check with stdout only"
31 chan = StringIO()
27 chan = StringIO()
32 text = 'Hello'
28 text = 'Hello'
33 tee = Tee(chan, channel='stdout')
29 tee = Tee(chan, channel='stdout')
34 print(text, file=chan)
30 print(text, file=chan)
35 nt.assert_equal(chan.getvalue(), text+"\n")
31 nt.assert_equal(chan.getvalue(), text+"\n")
36
32
37
33
38 class TeeTestCase(unittest.TestCase):
34 class TeeTestCase(unittest.TestCase):
39
35
40 def tchan(self, channel, check='close'):
36 def tchan(self, channel, check='close'):
41 trap = StringIO()
37 trap = StringIO()
42 chan = StringIO()
38 chan = StringIO()
43 text = 'Hello'
39 text = 'Hello'
44
40
45 std_ori = getattr(sys, channel)
41 std_ori = getattr(sys, channel)
46 setattr(sys, channel, trap)
42 setattr(sys, channel, trap)
47
43
48 tee = Tee(chan, channel=channel)
44 tee = Tee(chan, channel=channel)
49 print(text, end='', file=chan)
45 print(text, end='', file=chan)
50 setattr(sys, channel, std_ori)
46 setattr(sys, channel, std_ori)
51 trap_val = trap.getvalue()
47 trap_val = trap.getvalue()
52 nt.assert_equal(chan.getvalue(), text)
48 nt.assert_equal(chan.getvalue(), text)
53 if check=='close':
49 if check=='close':
54 tee.close()
50 tee.close()
55 else:
51 else:
56 del tee
52 del tee
57
53
58 def test(self):
54 def test(self):
59 for chan in ['stdout', 'stderr']:
55 for chan in ['stdout', 'stderr']:
60 for check in ['close', 'del']:
56 for check in ['close', 'del']:
61 self.tchan(chan, check)
57 self.tchan(chan, check)
62
58
63 def test_io_init():
59 def test_io_init():
64 """Test that io.stdin/out/err exist at startup"""
60 """Test that io.stdin/out/err exist at startup"""
65 for name in ('stdin', 'stdout', 'stderr'):
61 for name in ('stdin', 'stdout', 'stderr'):
66 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
62 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
67 p = Popen([sys.executable, '-c', cmd],
63 p = Popen([sys.executable, '-c', cmd],
68 stdout=PIPE)
64 stdout=PIPE)
69 p.wait()
65 p.wait()
70 classname = p.stdout.read().strip().decode('ascii')
66 classname = p.stdout.read().strip().decode('ascii')
71 # __class__ is a reference to the class object in Python 3, so we can't
67 # __class__ is a reference to the class object in Python 3, so we can't
72 # just test for string equality.
68 # just test for string equality.
73 assert 'IPython.utils.io.IOStream' in classname, classname
69 assert 'IPython.utils.io.IOStream' in classname, classname
74
70
75 def test_capture_output():
71 def test_capture_output():
76 """capture_output() context works"""
72 """capture_output() context works"""
77
73
78 with capture_output() as io:
74 with capture_output() as io:
79 print('hi, stdout')
75 print('hi, stdout')
80 print('hi, stderr', file=sys.stderr)
76 print('hi, stderr', file=sys.stderr)
81
77
82 nt.assert_equal(io.stdout, 'hi, stdout\n')
78 nt.assert_equal(io.stdout, 'hi, stdout\n')
83 nt.assert_equal(io.stderr, 'hi, stderr\n')
79 nt.assert_equal(io.stderr, 'hi, stderr\n')
84
80
85
81
@@ -1,44 +1,25 b''
1 """Wrapper around linecache which decodes files to unicode according to PEP 263.
1 """
2 This module has been deprecated since IPython 6.0.
2
3
3 This is only needed for Python 2 - linecache in Python 3 does the same thing
4 Wrapper around linecache which decodes files to unicode according to PEP 263.
4 itself.
5 """
5 """
6 import functools
6 import functools
7 import linecache
7 import linecache
8 import sys
8 import sys
9 from warnings import warn
9
10
10 from IPython.utils import py3compat
11 from IPython.utils import py3compat
11 from IPython.utils import openpy
12 from IPython.utils import openpy
12
13
13 if py3compat.PY3:
14 getline = linecache.getline
14 getline = linecache.getline
15
15
16 # getlines has to be looked up at runtime, because doctests monkeypatch it.
16 # getlines has to be looked up at runtime, because doctests monkeypatch it.
17 @functools.wraps(linecache.getlines)
17 @functools.wraps(linecache.getlines)
18 def getlines(filename, module_globals=None):
18 def getlines(filename, module_globals=None):
19 """
20 Deprecated since IPython 6.0
21 """
22 warn(("`IPython.utils.ulinecache.getlines` is deprecated since"
23 " IPython 6.0 and will be removed in future versions."),
24 DeprecationWarning, stacklevel=2)
19 return linecache.getlines(filename, module_globals=module_globals)
25 return linecache.getlines(filename, module_globals=module_globals)
20
21 else:
22 def getlines(filename, module_globals=None):
23 """Get the lines (as unicode) for a file from the cache.
24 Update the cache if it doesn't contain an entry for this file already."""
25 filename = py3compat.cast_bytes(filename, sys.getfilesystemencoding())
26 lines = linecache.getlines(filename, module_globals=module_globals)
27
28 if (not lines) or isinstance(lines[0], str):
29 return lines
30
31 readline = openpy._list_readline(lines)
32 try:
33 encoding, _ = openpy.detect_encoding(readline)
34 except SyntaxError:
35 encoding = 'ascii'
36 return [l.decode(encoding, 'replace') for l in lines]
37
38 # This is a straight copy of linecache.getline
39 def getline(filename, lineno, module_globals=None):
40 lines = getlines(filename, module_globals)
41 if 1 <= lineno <= len(lines):
42 return lines[lineno-1]
43 else:
44 return ''
General Comments 0
You need to be logged in to leave comments. Login now