##// END OF EJS Templates
Use the proper python2 pygments lexer...
Timo Kaufmann -
Show More
@@ -1,1011 +1,1015 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
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 from __future__ import print_function
13 from __future__ import print_function
14
14
15 __all__ = ['Inspector','InspectColors']
15 __all__ = ['Inspector','InspectColors']
16
16
17 # stdlib modules
17 # stdlib modules
18 import inspect
18 import inspect
19 import linecache
19 import linecache
20 import warnings
20 import warnings
21 import os
21 import os
22 from textwrap import dedent
22 from textwrap import dedent
23 import types
23 import types
24 import io as stdlib_io
24 import io as stdlib_io
25
25
26 try:
26 try:
27 from itertools import izip_longest
27 from itertools import izip_longest
28 except ImportError:
28 except ImportError:
29 from itertools import zip_longest as izip_longest
29 from itertools import zip_longest as izip_longest
30
30
31 # IPython's own
31 # IPython's own
32 from IPython.core import page
32 from IPython.core import page
33 from IPython.lib.pretty import pretty
33 from IPython.lib.pretty import pretty
34 from IPython.testing.skipdoctest import skip_doctest_py3
34 from IPython.testing.skipdoctest import skip_doctest_py3
35 from IPython.utils import PyColorize
35 from IPython.utils import PyColorize
36 from IPython.utils import openpy
36 from IPython.utils import openpy
37 from IPython.utils import py3compat
37 from IPython.utils import py3compat
38 from IPython.utils.dir2 import safe_hasattr
38 from IPython.utils.dir2 import safe_hasattr
39 from IPython.utils.path import compress_user
39 from IPython.utils.path import compress_user
40 from IPython.utils.text import indent
40 from IPython.utils.text import indent
41 from IPython.utils.wildcard import list_namespace
41 from IPython.utils.wildcard import list_namespace
42 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
42 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
43 from IPython.utils.py3compat import cast_unicode, string_types, PY3
43 from IPython.utils.py3compat import cast_unicode, string_types, PY3
44 from IPython.utils.signatures import signature
44 from IPython.utils.signatures import signature
45 from IPython.utils.colorable import Colorable
45 from IPython.utils.colorable import Colorable
46
46
47 from pygments import highlight
47 from pygments import highlight
48 from pygments.lexers import PythonLexer
48 try:
49 # PythonLexer was renamed to Python2Lexer in pygments 2.5
50 from pygments.lexers import Python2Lexer
51 except ImportError:
52 from pygments.lexers import PythonLexer as Python2Lexer
49 from pygments.formatters import HtmlFormatter
53 from pygments.formatters import HtmlFormatter
50
54
51 def pylight(code):
55 def pylight(code):
52 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
56 return highlight(code, Python2Lexer(), HtmlFormatter(noclasses=True))
53
57
54 # builtin docstrings to ignore
58 # builtin docstrings to ignore
55 _func_call_docstring = types.FunctionType.__call__.__doc__
59 _func_call_docstring = types.FunctionType.__call__.__doc__
56 _object_init_docstring = object.__init__.__doc__
60 _object_init_docstring = object.__init__.__doc__
57 _builtin_type_docstrings = {
61 _builtin_type_docstrings = {
58 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
62 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
59 types.FunctionType, property)
63 types.FunctionType, property)
60 }
64 }
61
65
62 _builtin_func_type = type(all)
66 _builtin_func_type = type(all)
63 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
67 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
64 #****************************************************************************
68 #****************************************************************************
65 # Builtin color schemes
69 # Builtin color schemes
66
70
67 Colors = TermColors # just a shorthand
71 Colors = TermColors # just a shorthand
68
72
69 InspectColors = PyColorize.ANSICodeColors
73 InspectColors = PyColorize.ANSICodeColors
70
74
71 #****************************************************************************
75 #****************************************************************************
72 # Auxiliary functions and objects
76 # Auxiliary functions and objects
73
77
74 # See the messaging spec for the definition of all these fields. This list
78 # See the messaging spec for the definition of all these fields. This list
75 # effectively defines the order of display
79 # effectively defines the order of display
76 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
80 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
77 'length', 'file', 'definition', 'docstring', 'source',
81 'length', 'file', 'definition', 'docstring', 'source',
78 'init_definition', 'class_docstring', 'init_docstring',
82 'init_definition', 'class_docstring', 'init_docstring',
79 'call_def', 'call_docstring',
83 'call_def', 'call_docstring',
80 # These won't be printed but will be used to determine how to
84 # These won't be printed but will be used to determine how to
81 # format the object
85 # format the object
82 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
86 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
83 ]
87 ]
84
88
85
89
86 def object_info(**kw):
90 def object_info(**kw):
87 """Make an object info dict with all fields present."""
91 """Make an object info dict with all fields present."""
88 infodict = dict(izip_longest(info_fields, [None]))
92 infodict = dict(izip_longest(info_fields, [None]))
89 infodict.update(kw)
93 infodict.update(kw)
90 return infodict
94 return infodict
91
95
92
96
93 def get_encoding(obj):
97 def get_encoding(obj):
94 """Get encoding for python source file defining obj
98 """Get encoding for python source file defining obj
95
99
96 Returns None if obj is not defined in a sourcefile.
100 Returns None if obj is not defined in a sourcefile.
97 """
101 """
98 ofile = find_file(obj)
102 ofile = find_file(obj)
99 # run contents of file through pager starting at line where the object
103 # run contents of file through pager starting at line where the object
100 # is defined, as long as the file isn't binary and is actually on the
104 # is defined, as long as the file isn't binary and is actually on the
101 # filesystem.
105 # filesystem.
102 if ofile is None:
106 if ofile is None:
103 return None
107 return None
104 elif ofile.endswith(('.so', '.dll', '.pyd')):
108 elif ofile.endswith(('.so', '.dll', '.pyd')):
105 return None
109 return None
106 elif not os.path.isfile(ofile):
110 elif not os.path.isfile(ofile):
107 return None
111 return None
108 else:
112 else:
109 # Print only text files, not extension binaries. Note that
113 # Print only text files, not extension binaries. Note that
110 # getsourcelines returns lineno with 1-offset and page() uses
114 # getsourcelines returns lineno with 1-offset and page() uses
111 # 0-offset, so we must adjust.
115 # 0-offset, so we must adjust.
112 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
116 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
113 encoding, lines = openpy.detect_encoding(buffer.readline)
117 encoding, lines = openpy.detect_encoding(buffer.readline)
114 return encoding
118 return encoding
115
119
116 def getdoc(obj):
120 def getdoc(obj):
117 """Stable wrapper around inspect.getdoc.
121 """Stable wrapper around inspect.getdoc.
118
122
119 This can't crash because of attribute problems.
123 This can't crash because of attribute problems.
120
124
121 It also attempts to call a getdoc() method on the given object. This
125 It also attempts to call a getdoc() method on the given object. This
122 allows objects which provide their docstrings via non-standard mechanisms
126 allows objects which provide their docstrings via non-standard mechanisms
123 (like Pyro proxies) to still be inspected by ipython's ? system.
127 (like Pyro proxies) to still be inspected by ipython's ? system.
124 """
128 """
125 # Allow objects to offer customized documentation via a getdoc method:
129 # Allow objects to offer customized documentation via a getdoc method:
126 try:
130 try:
127 ds = obj.getdoc()
131 ds = obj.getdoc()
128 except Exception:
132 except Exception:
129 pass
133 pass
130 else:
134 else:
131 # if we get extra info, we add it to the normal docstring.
135 # if we get extra info, we add it to the normal docstring.
132 if isinstance(ds, string_types):
136 if isinstance(ds, string_types):
133 return inspect.cleandoc(ds)
137 return inspect.cleandoc(ds)
134 try:
138 try:
135 docstr = inspect.getdoc(obj)
139 docstr = inspect.getdoc(obj)
136 encoding = get_encoding(obj)
140 encoding = get_encoding(obj)
137 return py3compat.cast_unicode(docstr, encoding=encoding)
141 return py3compat.cast_unicode(docstr, encoding=encoding)
138 except Exception:
142 except Exception:
139 # Harden against an inspect failure, which can occur with
143 # Harden against an inspect failure, which can occur with
140 # extensions modules.
144 # extensions modules.
141 raise
145 raise
142 return None
146 return None
143
147
144
148
145 def getsource(obj, oname=''):
149 def getsource(obj, oname=''):
146 """Wrapper around inspect.getsource.
150 """Wrapper around inspect.getsource.
147
151
148 This can be modified by other projects to provide customized source
152 This can be modified by other projects to provide customized source
149 extraction.
153 extraction.
150
154
151 Parameters
155 Parameters
152 ----------
156 ----------
153 obj : object
157 obj : object
154 an object whose source code we will attempt to extract
158 an object whose source code we will attempt to extract
155 oname : str
159 oname : str
156 (optional) a name under which the object is known
160 (optional) a name under which the object is known
157
161
158 Returns
162 Returns
159 -------
163 -------
160 src : unicode or None
164 src : unicode or None
161
165
162 """
166 """
163
167
164 if isinstance(obj, property):
168 if isinstance(obj, property):
165 sources = []
169 sources = []
166 for attrname in ['fget', 'fset', 'fdel']:
170 for attrname in ['fget', 'fset', 'fdel']:
167 fn = getattr(obj, attrname)
171 fn = getattr(obj, attrname)
168 if fn is not None:
172 if fn is not None:
169 encoding = get_encoding(fn)
173 encoding = get_encoding(fn)
170 oname_prefix = ('%s.' % oname) if oname else ''
174 oname_prefix = ('%s.' % oname) if oname else ''
171 sources.append(cast_unicode(
175 sources.append(cast_unicode(
172 ''.join(('# ', oname_prefix, attrname)),
176 ''.join(('# ', oname_prefix, attrname)),
173 encoding=encoding))
177 encoding=encoding))
174 if inspect.isfunction(fn):
178 if inspect.isfunction(fn):
175 sources.append(dedent(getsource(fn)))
179 sources.append(dedent(getsource(fn)))
176 else:
180 else:
177 # Default str/repr only prints function name,
181 # Default str/repr only prints function name,
178 # pretty.pretty prints module name too.
182 # pretty.pretty prints module name too.
179 sources.append(cast_unicode(
183 sources.append(cast_unicode(
180 '%s%s = %s\n' % (
184 '%s%s = %s\n' % (
181 oname_prefix, attrname, pretty(fn)),
185 oname_prefix, attrname, pretty(fn)),
182 encoding=encoding))
186 encoding=encoding))
183 if sources:
187 if sources:
184 return '\n'.join(sources)
188 return '\n'.join(sources)
185 else:
189 else:
186 return None
190 return None
187
191
188 else:
192 else:
189 # Get source for non-property objects.
193 # Get source for non-property objects.
190
194
191 obj = _get_wrapped(obj)
195 obj = _get_wrapped(obj)
192
196
193 try:
197 try:
194 src = inspect.getsource(obj)
198 src = inspect.getsource(obj)
195 except TypeError:
199 except TypeError:
196 # The object itself provided no meaningful source, try looking for
200 # The object itself provided no meaningful source, try looking for
197 # its class definition instead.
201 # its class definition instead.
198 if hasattr(obj, '__class__'):
202 if hasattr(obj, '__class__'):
199 try:
203 try:
200 src = inspect.getsource(obj.__class__)
204 src = inspect.getsource(obj.__class__)
201 except TypeError:
205 except TypeError:
202 return None
206 return None
203
207
204 encoding = get_encoding(obj)
208 encoding = get_encoding(obj)
205 return cast_unicode(src, encoding=encoding)
209 return cast_unicode(src, encoding=encoding)
206
210
207
211
208 def is_simple_callable(obj):
212 def is_simple_callable(obj):
209 """True if obj is a function ()"""
213 """True if obj is a function ()"""
210 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
214 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
211 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
215 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
212
216
213
217
214 def getargspec(obj):
218 def getargspec(obj):
215 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
219 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
216 :func:inspect.getargspec` on Python 2.
220 :func:inspect.getargspec` on Python 2.
217
221
218 In addition to functions and methods, this can also handle objects with a
222 In addition to functions and methods, this can also handle objects with a
219 ``__call__`` attribute.
223 ``__call__`` attribute.
220 """
224 """
221 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
225 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
222 obj = obj.__call__
226 obj = obj.__call__
223
227
224 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
228 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
225
229
226
230
227 def format_argspec(argspec):
231 def format_argspec(argspec):
228 """Format argspect, convenience wrapper around inspect's.
232 """Format argspect, convenience wrapper around inspect's.
229
233
230 This takes a dict instead of ordered arguments and calls
234 This takes a dict instead of ordered arguments and calls
231 inspect.format_argspec with the arguments in the necessary order.
235 inspect.format_argspec with the arguments in the necessary order.
232 """
236 """
233 return inspect.formatargspec(argspec['args'], argspec['varargs'],
237 return inspect.formatargspec(argspec['args'], argspec['varargs'],
234 argspec['varkw'], argspec['defaults'])
238 argspec['varkw'], argspec['defaults'])
235
239
236
240
237 def call_tip(oinfo, format_call=True):
241 def call_tip(oinfo, format_call=True):
238 """Extract call tip data from an oinfo dict.
242 """Extract call tip data from an oinfo dict.
239
243
240 Parameters
244 Parameters
241 ----------
245 ----------
242 oinfo : dict
246 oinfo : dict
243
247
244 format_call : bool, optional
248 format_call : bool, optional
245 If True, the call line is formatted and returned as a string. If not, a
249 If True, the call line is formatted and returned as a string. If not, a
246 tuple of (name, argspec) is returned.
250 tuple of (name, argspec) is returned.
247
251
248 Returns
252 Returns
249 -------
253 -------
250 call_info : None, str or (str, dict) tuple.
254 call_info : None, str or (str, dict) tuple.
251 When format_call is True, the whole call information is formattted as a
255 When format_call is True, the whole call information is formattted as a
252 single string. Otherwise, the object's name and its argspec dict are
256 single string. Otherwise, the object's name and its argspec dict are
253 returned. If no call information is available, None is returned.
257 returned. If no call information is available, None is returned.
254
258
255 docstring : str or None
259 docstring : str or None
256 The most relevant docstring for calling purposes is returned, if
260 The most relevant docstring for calling purposes is returned, if
257 available. The priority is: call docstring for callable instances, then
261 available. The priority is: call docstring for callable instances, then
258 constructor docstring for classes, then main object's docstring otherwise
262 constructor docstring for classes, then main object's docstring otherwise
259 (regular functions).
263 (regular functions).
260 """
264 """
261 # Get call definition
265 # Get call definition
262 argspec = oinfo.get('argspec')
266 argspec = oinfo.get('argspec')
263 if argspec is None:
267 if argspec is None:
264 call_line = None
268 call_line = None
265 else:
269 else:
266 # Callable objects will have 'self' as their first argument, prune
270 # Callable objects will have 'self' as their first argument, prune
267 # it out if it's there for clarity (since users do *not* pass an
271 # it out if it's there for clarity (since users do *not* pass an
268 # extra first argument explicitly).
272 # extra first argument explicitly).
269 try:
273 try:
270 has_self = argspec['args'][0] == 'self'
274 has_self = argspec['args'][0] == 'self'
271 except (KeyError, IndexError):
275 except (KeyError, IndexError):
272 pass
276 pass
273 else:
277 else:
274 if has_self:
278 if has_self:
275 argspec['args'] = argspec['args'][1:]
279 argspec['args'] = argspec['args'][1:]
276
280
277 call_line = oinfo['name']+format_argspec(argspec)
281 call_line = oinfo['name']+format_argspec(argspec)
278
282
279 # Now get docstring.
283 # Now get docstring.
280 # The priority is: call docstring, constructor docstring, main one.
284 # The priority is: call docstring, constructor docstring, main one.
281 doc = oinfo.get('call_docstring')
285 doc = oinfo.get('call_docstring')
282 if doc is None:
286 if doc is None:
283 doc = oinfo.get('init_docstring')
287 doc = oinfo.get('init_docstring')
284 if doc is None:
288 if doc is None:
285 doc = oinfo.get('docstring','')
289 doc = oinfo.get('docstring','')
286
290
287 return call_line, doc
291 return call_line, doc
288
292
289
293
290 def _get_wrapped(obj):
294 def _get_wrapped(obj):
291 """Get the original object if wrapped in one or more @decorators
295 """Get the original object if wrapped in one or more @decorators
292
296
293 Some objects automatically construct similar objects on any unrecognised
297 Some objects automatically construct similar objects on any unrecognised
294 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
298 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
295 this will arbitrarily cut off after 100 levels of obj.__wrapped__
299 this will arbitrarily cut off after 100 levels of obj.__wrapped__
296 attribute access. --TK, Jan 2016
300 attribute access. --TK, Jan 2016
297 """
301 """
298 orig_obj = obj
302 orig_obj = obj
299 i = 0
303 i = 0
300 while safe_hasattr(obj, '__wrapped__'):
304 while safe_hasattr(obj, '__wrapped__'):
301 obj = obj.__wrapped__
305 obj = obj.__wrapped__
302 i += 1
306 i += 1
303 if i > 100:
307 if i > 100:
304 # __wrapped__ is probably a lie, so return the thing we started with
308 # __wrapped__ is probably a lie, so return the thing we started with
305 return orig_obj
309 return orig_obj
306 return obj
310 return obj
307
311
308 def find_file(obj):
312 def find_file(obj):
309 """Find the absolute path to the file where an object was defined.
313 """Find the absolute path to the file where an object was defined.
310
314
311 This is essentially a robust wrapper around `inspect.getabsfile`.
315 This is essentially a robust wrapper around `inspect.getabsfile`.
312
316
313 Returns None if no file can be found.
317 Returns None if no file can be found.
314
318
315 Parameters
319 Parameters
316 ----------
320 ----------
317 obj : any Python object
321 obj : any Python object
318
322
319 Returns
323 Returns
320 -------
324 -------
321 fname : str
325 fname : str
322 The absolute path to the file where the object was defined.
326 The absolute path to the file where the object was defined.
323 """
327 """
324 obj = _get_wrapped(obj)
328 obj = _get_wrapped(obj)
325
329
326 fname = None
330 fname = None
327 try:
331 try:
328 fname = inspect.getabsfile(obj)
332 fname = inspect.getabsfile(obj)
329 except TypeError:
333 except TypeError:
330 # For an instance, the file that matters is where its class was
334 # For an instance, the file that matters is where its class was
331 # declared.
335 # declared.
332 if hasattr(obj, '__class__'):
336 if hasattr(obj, '__class__'):
333 try:
337 try:
334 fname = inspect.getabsfile(obj.__class__)
338 fname = inspect.getabsfile(obj.__class__)
335 except TypeError:
339 except TypeError:
336 # Can happen for builtins
340 # Can happen for builtins
337 pass
341 pass
338 except:
342 except:
339 pass
343 pass
340 return cast_unicode(fname)
344 return cast_unicode(fname)
341
345
342
346
343 def find_source_lines(obj):
347 def find_source_lines(obj):
344 """Find the line number in a file where an object was defined.
348 """Find the line number in a file where an object was defined.
345
349
346 This is essentially a robust wrapper around `inspect.getsourcelines`.
350 This is essentially a robust wrapper around `inspect.getsourcelines`.
347
351
348 Returns None if no file can be found.
352 Returns None if no file can be found.
349
353
350 Parameters
354 Parameters
351 ----------
355 ----------
352 obj : any Python object
356 obj : any Python object
353
357
354 Returns
358 Returns
355 -------
359 -------
356 lineno : int
360 lineno : int
357 The line number where the object definition starts.
361 The line number where the object definition starts.
358 """
362 """
359 obj = _get_wrapped(obj)
363 obj = _get_wrapped(obj)
360
364
361 try:
365 try:
362 try:
366 try:
363 lineno = inspect.getsourcelines(obj)[1]
367 lineno = inspect.getsourcelines(obj)[1]
364 except TypeError:
368 except TypeError:
365 # For instances, try the class object like getsource() does
369 # For instances, try the class object like getsource() does
366 if hasattr(obj, '__class__'):
370 if hasattr(obj, '__class__'):
367 lineno = inspect.getsourcelines(obj.__class__)[1]
371 lineno = inspect.getsourcelines(obj.__class__)[1]
368 else:
372 else:
369 lineno = None
373 lineno = None
370 except:
374 except:
371 return None
375 return None
372
376
373 return lineno
377 return lineno
374
378
375 class Inspector(Colorable):
379 class Inspector(Colorable):
376
380
377 def __init__(self, color_table=InspectColors,
381 def __init__(self, color_table=InspectColors,
378 code_color_table=PyColorize.ANSICodeColors,
382 code_color_table=PyColorize.ANSICodeColors,
379 scheme='NoColor',
383 scheme='NoColor',
380 str_detail_level=0,
384 str_detail_level=0,
381 parent=None, config=None):
385 parent=None, config=None):
382 super(Inspector, self).__init__(parent=parent, config=config)
386 super(Inspector, self).__init__(parent=parent, config=config)
383 self.color_table = color_table
387 self.color_table = color_table
384 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
388 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
385 self.format = self.parser.format
389 self.format = self.parser.format
386 self.str_detail_level = str_detail_level
390 self.str_detail_level = str_detail_level
387 self.set_active_scheme(scheme)
391 self.set_active_scheme(scheme)
388
392
389 def _getdef(self,obj,oname=''):
393 def _getdef(self,obj,oname=''):
390 """Return the call signature for any callable object.
394 """Return the call signature for any callable object.
391
395
392 If any exception is generated, None is returned instead and the
396 If any exception is generated, None is returned instead and the
393 exception is suppressed."""
397 exception is suppressed."""
394 try:
398 try:
395 hdef = oname + str(signature(obj))
399 hdef = oname + str(signature(obj))
396 return cast_unicode(hdef)
400 return cast_unicode(hdef)
397 except:
401 except:
398 return None
402 return None
399
403
400 def __head(self,h):
404 def __head(self,h):
401 """Return a header string with proper colors."""
405 """Return a header string with proper colors."""
402 return '%s%s%s' % (self.color_table.active_colors.header,h,
406 return '%s%s%s' % (self.color_table.active_colors.header,h,
403 self.color_table.active_colors.normal)
407 self.color_table.active_colors.normal)
404
408
405 def set_active_scheme(self, scheme):
409 def set_active_scheme(self, scheme):
406 self.color_table.set_active_scheme(scheme)
410 self.color_table.set_active_scheme(scheme)
407 self.parser.color_table.set_active_scheme(scheme)
411 self.parser.color_table.set_active_scheme(scheme)
408
412
409 def noinfo(self, msg, oname):
413 def noinfo(self, msg, oname):
410 """Generic message when no information is found."""
414 """Generic message when no information is found."""
411 print('No %s found' % msg, end=' ')
415 print('No %s found' % msg, end=' ')
412 if oname:
416 if oname:
413 print('for %s' % oname)
417 print('for %s' % oname)
414 else:
418 else:
415 print()
419 print()
416
420
417 def pdef(self, obj, oname=''):
421 def pdef(self, obj, oname=''):
418 """Print the call signature for any callable object.
422 """Print the call signature for any callable object.
419
423
420 If the object is a class, print the constructor information."""
424 If the object is a class, print the constructor information."""
421
425
422 if not callable(obj):
426 if not callable(obj):
423 print('Object is not callable.')
427 print('Object is not callable.')
424 return
428 return
425
429
426 header = ''
430 header = ''
427
431
428 if inspect.isclass(obj):
432 if inspect.isclass(obj):
429 header = self.__head('Class constructor information:\n')
433 header = self.__head('Class constructor information:\n')
430 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
434 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
431 obj = obj.__call__
435 obj = obj.__call__
432
436
433 output = self._getdef(obj,oname)
437 output = self._getdef(obj,oname)
434 if output is None:
438 if output is None:
435 self.noinfo('definition header',oname)
439 self.noinfo('definition header',oname)
436 else:
440 else:
437 print(header,self.format(output), end=' ')
441 print(header,self.format(output), end=' ')
438
442
439 # In Python 3, all classes are new-style, so they all have __init__.
443 # In Python 3, all classes are new-style, so they all have __init__.
440 @skip_doctest_py3
444 @skip_doctest_py3
441 def pdoc(self, obj, oname='', formatter=None):
445 def pdoc(self, obj, oname='', formatter=None):
442 """Print the docstring for any object.
446 """Print the docstring for any object.
443
447
444 Optional:
448 Optional:
445 -formatter: a function to run the docstring through for specially
449 -formatter: a function to run the docstring through for specially
446 formatted docstrings.
450 formatted docstrings.
447
451
448 Examples
452 Examples
449 --------
453 --------
450
454
451 In [1]: class NoInit:
455 In [1]: class NoInit:
452 ...: pass
456 ...: pass
453
457
454 In [2]: class NoDoc:
458 In [2]: class NoDoc:
455 ...: def __init__(self):
459 ...: def __init__(self):
456 ...: pass
460 ...: pass
457
461
458 In [3]: %pdoc NoDoc
462 In [3]: %pdoc NoDoc
459 No documentation found for NoDoc
463 No documentation found for NoDoc
460
464
461 In [4]: %pdoc NoInit
465 In [4]: %pdoc NoInit
462 No documentation found for NoInit
466 No documentation found for NoInit
463
467
464 In [5]: obj = NoInit()
468 In [5]: obj = NoInit()
465
469
466 In [6]: %pdoc obj
470 In [6]: %pdoc obj
467 No documentation found for obj
471 No documentation found for obj
468
472
469 In [5]: obj2 = NoDoc()
473 In [5]: obj2 = NoDoc()
470
474
471 In [6]: %pdoc obj2
475 In [6]: %pdoc obj2
472 No documentation found for obj2
476 No documentation found for obj2
473 """
477 """
474
478
475 head = self.__head # For convenience
479 head = self.__head # For convenience
476 lines = []
480 lines = []
477 ds = getdoc(obj)
481 ds = getdoc(obj)
478 if formatter:
482 if formatter:
479 ds = formatter(ds).get('plain/text', ds)
483 ds = formatter(ds).get('plain/text', ds)
480 if ds:
484 if ds:
481 lines.append(head("Class docstring:"))
485 lines.append(head("Class docstring:"))
482 lines.append(indent(ds))
486 lines.append(indent(ds))
483 if inspect.isclass(obj) and hasattr(obj, '__init__'):
487 if inspect.isclass(obj) and hasattr(obj, '__init__'):
484 init_ds = getdoc(obj.__init__)
488 init_ds = getdoc(obj.__init__)
485 if init_ds is not None:
489 if init_ds is not None:
486 lines.append(head("Init docstring:"))
490 lines.append(head("Init docstring:"))
487 lines.append(indent(init_ds))
491 lines.append(indent(init_ds))
488 elif hasattr(obj,'__call__'):
492 elif hasattr(obj,'__call__'):
489 call_ds = getdoc(obj.__call__)
493 call_ds = getdoc(obj.__call__)
490 if call_ds:
494 if call_ds:
491 lines.append(head("Call docstring:"))
495 lines.append(head("Call docstring:"))
492 lines.append(indent(call_ds))
496 lines.append(indent(call_ds))
493
497
494 if not lines:
498 if not lines:
495 self.noinfo('documentation',oname)
499 self.noinfo('documentation',oname)
496 else:
500 else:
497 page.page('\n'.join(lines))
501 page.page('\n'.join(lines))
498
502
499 def psource(self, obj, oname=''):
503 def psource(self, obj, oname=''):
500 """Print the source code for an object."""
504 """Print the source code for an object."""
501
505
502 # Flush the source cache because inspect can return out-of-date source
506 # Flush the source cache because inspect can return out-of-date source
503 linecache.checkcache()
507 linecache.checkcache()
504 try:
508 try:
505 src = getsource(obj, oname=oname)
509 src = getsource(obj, oname=oname)
506 except Exception:
510 except Exception:
507 src = None
511 src = None
508
512
509 if src is None:
513 if src is None:
510 self.noinfo('source', oname)
514 self.noinfo('source', oname)
511 else:
515 else:
512 page.page(self.format(src))
516 page.page(self.format(src))
513
517
514 def pfile(self, obj, oname=''):
518 def pfile(self, obj, oname=''):
515 """Show the whole file where an object was defined."""
519 """Show the whole file where an object was defined."""
516
520
517 lineno = find_source_lines(obj)
521 lineno = find_source_lines(obj)
518 if lineno is None:
522 if lineno is None:
519 self.noinfo('file', oname)
523 self.noinfo('file', oname)
520 return
524 return
521
525
522 ofile = find_file(obj)
526 ofile = find_file(obj)
523 # run contents of file through pager starting at line where the object
527 # run contents of file through pager starting at line where the object
524 # is defined, as long as the file isn't binary and is actually on the
528 # is defined, as long as the file isn't binary and is actually on the
525 # filesystem.
529 # filesystem.
526 if ofile.endswith(('.so', '.dll', '.pyd')):
530 if ofile.endswith(('.so', '.dll', '.pyd')):
527 print('File %r is binary, not printing.' % ofile)
531 print('File %r is binary, not printing.' % ofile)
528 elif not os.path.isfile(ofile):
532 elif not os.path.isfile(ofile):
529 print('File %r does not exist, not printing.' % ofile)
533 print('File %r does not exist, not printing.' % ofile)
530 else:
534 else:
531 # Print only text files, not extension binaries. Note that
535 # Print only text files, not extension binaries. Note that
532 # getsourcelines returns lineno with 1-offset and page() uses
536 # getsourcelines returns lineno with 1-offset and page() uses
533 # 0-offset, so we must adjust.
537 # 0-offset, so we must adjust.
534 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
538 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
535
539
536 def _format_fields(self, fields, title_width=0):
540 def _format_fields(self, fields, title_width=0):
537 """Formats a list of fields for display.
541 """Formats a list of fields for display.
538
542
539 Parameters
543 Parameters
540 ----------
544 ----------
541 fields : list
545 fields : list
542 A list of 2-tuples: (field_title, field_content)
546 A list of 2-tuples: (field_title, field_content)
543 title_width : int
547 title_width : int
544 How many characters to pad titles to. Default to longest title.
548 How many characters to pad titles to. Default to longest title.
545 """
549 """
546 out = []
550 out = []
547 header = self.__head
551 header = self.__head
548 if title_width == 0:
552 if title_width == 0:
549 title_width = max(len(title) + 2 for title, _ in fields)
553 title_width = max(len(title) + 2 for title, _ in fields)
550 for title, content in fields:
554 for title, content in fields:
551 if len(content.splitlines()) > 1:
555 if len(content.splitlines()) > 1:
552 title = header(title + ':') + '\n'
556 title = header(title + ':') + '\n'
553 else:
557 else:
554 title = header((title + ':').ljust(title_width))
558 title = header((title + ':').ljust(title_width))
555 out.append(cast_unicode(title) + cast_unicode(content))
559 out.append(cast_unicode(title) + cast_unicode(content))
556 return "\n".join(out)
560 return "\n".join(out)
557
561
558 def _mime_format(self, text, formatter=None):
562 def _mime_format(self, text, formatter=None):
559 """Return a mime bundle representation of the input text.
563 """Return a mime bundle representation of the input text.
560
564
561 - if `formatter` is None, the returned mime bundle has
565 - if `formatter` is None, the returned mime bundle has
562 a `text/plain` field, with the input text.
566 a `text/plain` field, with the input text.
563 a `text/html` field with a `<pre>` tag containing the input text.
567 a `text/html` field with a `<pre>` tag containing the input text.
564
568
565 - if `formatter` is not None, it must be a callable transforming the
569 - if `formatter` is not None, it must be a callable transforming the
566 input text into a mime bundle. Default values for `text/plain` and
570 input text into a mime bundle. Default values for `text/plain` and
567 `text/html` representations are the ones described above.
571 `text/html` representations are the ones described above.
568
572
569 Note:
573 Note:
570
574
571 Formatters returning strings are supported but this behavior is deprecated.
575 Formatters returning strings are supported but this behavior is deprecated.
572
576
573 """
577 """
574 text = cast_unicode(text)
578 text = cast_unicode(text)
575 defaults = {
579 defaults = {
576 'text/plain': text,
580 'text/plain': text,
577 'text/html': '<pre>' + text + '</pre>'
581 'text/html': '<pre>' + text + '</pre>'
578 }
582 }
579
583
580 if formatter is None:
584 if formatter is None:
581 return defaults
585 return defaults
582 else:
586 else:
583 formatted = formatter(text)
587 formatted = formatter(text)
584
588
585 if not isinstance(formatted, dict):
589 if not isinstance(formatted, dict):
586 # Handle the deprecated behavior of a formatter returning
590 # Handle the deprecated behavior of a formatter returning
587 # a string instead of a mime bundle.
591 # a string instead of a mime bundle.
588 return {
592 return {
589 'text/plain': formatted,
593 'text/plain': formatted,
590 'text/html': '<pre>' + formatted + '</pre>'
594 'text/html': '<pre>' + formatted + '</pre>'
591 }
595 }
592
596
593 else:
597 else:
594 return dict(defaults, **formatted)
598 return dict(defaults, **formatted)
595
599
596
600
597 def format_mime(self, bundle):
601 def format_mime(self, bundle):
598
602
599 text_plain = bundle['text/plain']
603 text_plain = bundle['text/plain']
600
604
601 text = ''
605 text = ''
602 heads, bodies = list(zip(*text_plain))
606 heads, bodies = list(zip(*text_plain))
603 _len = max(len(h) for h in heads)
607 _len = max(len(h) for h in heads)
604
608
605 for head, body in zip(heads, bodies):
609 for head, body in zip(heads, bodies):
606 body = body.strip('\n')
610 body = body.strip('\n')
607 delim = '\n' if '\n' in body else ' '
611 delim = '\n' if '\n' in body else ' '
608 text += self.__head(head+':') + (_len - len(head))*' ' +delim + body +'\n'
612 text += self.__head(head+':') + (_len - len(head))*' ' +delim + body +'\n'
609
613
610 bundle['text/plain'] = text
614 bundle['text/plain'] = text
611 return bundle
615 return bundle
612
616
613 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
617 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
614 """Retrieve an info dict and format it."""
618 """Retrieve an info dict and format it."""
615
619
616 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
620 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
617
621
618 _mime = {
622 _mime = {
619 'text/plain': [],
623 'text/plain': [],
620 'text/html': '',
624 'text/html': '',
621 }
625 }
622
626
623 def append_field(bundle, title, key, formatter=None):
627 def append_field(bundle, title, key, formatter=None):
624 field = info[key]
628 field = info[key]
625 if field is not None:
629 if field is not None:
626 formatted_field = self._mime_format(field, formatter)
630 formatted_field = self._mime_format(field, formatter)
627 bundle['text/plain'].append((title, formatted_field['text/plain']))
631 bundle['text/plain'].append((title, formatted_field['text/plain']))
628 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
632 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
629
633
630 def code_formatter(text):
634 def code_formatter(text):
631 return {
635 return {
632 'text/plain': self.format(text),
636 'text/plain': self.format(text),
633 'text/html': pylight(text)
637 'text/html': pylight(text)
634 }
638 }
635
639
636 if info['isalias']:
640 if info['isalias']:
637 append_field(_mime, 'Repr', 'string_form')
641 append_field(_mime, 'Repr', 'string_form')
638
642
639 elif info['ismagic']:
643 elif info['ismagic']:
640 if detail_level > 0:
644 if detail_level > 0:
641 append_field(_mime, 'Source', 'source', code_formatter)
645 append_field(_mime, 'Source', 'source', code_formatter)
642 else:
646 else:
643 append_field(_mime, 'Docstring', 'docstring', formatter)
647 append_field(_mime, 'Docstring', 'docstring', formatter)
644 append_field(_mime, 'File', 'file')
648 append_field(_mime, 'File', 'file')
645
649
646 elif info['isclass'] or is_simple_callable(obj):
650 elif info['isclass'] or is_simple_callable(obj):
647 # Functions, methods, classes
651 # Functions, methods, classes
648 append_field(_mime, 'Signature', 'definition', code_formatter)
652 append_field(_mime, 'Signature', 'definition', code_formatter)
649 append_field(_mime, 'Init signature', 'init_definition', code_formatter)
653 append_field(_mime, 'Init signature', 'init_definition', code_formatter)
650 if detail_level > 0 and info['source']:
654 if detail_level > 0 and info['source']:
651 append_field(_mime, 'Source', 'source', code_formatter)
655 append_field(_mime, 'Source', 'source', code_formatter)
652 else:
656 else:
653 append_field(_mime, 'Docstring', 'docstring', formatter)
657 append_field(_mime, 'Docstring', 'docstring', formatter)
654 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
658 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
655
659
656 append_field(_mime, 'File', 'file')
660 append_field(_mime, 'File', 'file')
657 append_field(_mime, 'Type', 'type_name')
661 append_field(_mime, 'Type', 'type_name')
658
662
659 else:
663 else:
660 # General Python objects
664 # General Python objects
661 append_field(_mime, 'Signature', 'definition', code_formatter)
665 append_field(_mime, 'Signature', 'definition', code_formatter)
662 append_field(_mime, 'Call signature', 'call_def', code_formatter)
666 append_field(_mime, 'Call signature', 'call_def', code_formatter)
663
667
664 append_field(_mime, 'Type', 'type_name')
668 append_field(_mime, 'Type', 'type_name')
665
669
666 # Base class for old-style instances
670 # Base class for old-style instances
667 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
671 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
668 append_field(_mime, 'Base Class', 'base_class')
672 append_field(_mime, 'Base Class', 'base_class')
669
673
670 append_field(_mime, 'String form', 'string_form')
674 append_field(_mime, 'String form', 'string_form')
671
675
672 # Namespace
676 # Namespace
673 if info['namespace'] != 'Interactive':
677 if info['namespace'] != 'Interactive':
674 append_field(_mime, 'Namespace', 'namespace')
678 append_field(_mime, 'Namespace', 'namespace')
675
679
676 append_field(_mime, 'Length', 'length')
680 append_field(_mime, 'Length', 'length')
677 append_field(_mime, 'File', 'file')
681 append_field(_mime, 'File', 'file')
678
682
679 # Source or docstring, depending on detail level and whether
683 # Source or docstring, depending on detail level and whether
680 # source found.
684 # source found.
681 if detail_level > 0:
685 if detail_level > 0:
682 append_field(_mime, 'Source', 'source', code_formatter)
686 append_field(_mime, 'Source', 'source', code_formatter)
683 else:
687 else:
684 append_field(_mime, 'Docstring', 'docstring', formatter)
688 append_field(_mime, 'Docstring', 'docstring', formatter)
685
689
686 append_field(_mime, 'Class docstring', 'class_docstring', formatter)
690 append_field(_mime, 'Class docstring', 'class_docstring', formatter)
687 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
691 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
688 append_field(_mime, 'Call docstring', 'call_docstring', formatter)
692 append_field(_mime, 'Call docstring', 'call_docstring', formatter)
689
693
690
694
691 return self.format_mime(_mime)
695 return self.format_mime(_mime)
692
696
693 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True):
697 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True):
694 """Show detailed information about an object.
698 """Show detailed information about an object.
695
699
696 Optional arguments:
700 Optional arguments:
697
701
698 - oname: name of the variable pointing to the object.
702 - oname: name of the variable pointing to the object.
699
703
700 - formatter: callable (optional)
704 - formatter: callable (optional)
701 A special formatter for docstrings.
705 A special formatter for docstrings.
702
706
703 The formatter is a callable that takes a string as an input
707 The formatter is a callable that takes a string as an input
704 and returns either a formatted string or a mime type bundle
708 and returns either a formatted string or a mime type bundle
705 in the form of a dictionnary.
709 in the form of a dictionnary.
706
710
707 Although the support of custom formatter returning a string
711 Although the support of custom formatter returning a string
708 instead of a mime type bundle is deprecated.
712 instead of a mime type bundle is deprecated.
709
713
710 - info: a structure with some information fields which may have been
714 - info: a structure with some information fields which may have been
711 precomputed already.
715 precomputed already.
712
716
713 - detail_level: if set to 1, more information is given.
717 - detail_level: if set to 1, more information is given.
714 """
718 """
715 info = self._get_info(obj, oname, formatter, info, detail_level)
719 info = self._get_info(obj, oname, formatter, info, detail_level)
716 if not enable_html_pager:
720 if not enable_html_pager:
717 del info['text/html']
721 del info['text/html']
718 page.page(info)
722 page.page(info)
719
723
720 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
724 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
721 """DEPRECATED. Compute a dict with detailed information about an object.
725 """DEPRECATED. Compute a dict with detailed information about an object.
722 """
726 """
723 if formatter is not None:
727 if formatter is not None:
724 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
728 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
725 'is deprecated as of IPython 5.0 and will have no effects.',
729 'is deprecated as of IPython 5.0 and will have no effects.',
726 DeprecationWarning, stacklevel=2)
730 DeprecationWarning, stacklevel=2)
727 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
731 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
728
732
729 def _info(self, obj, oname='', info=None, detail_level=0):
733 def _info(self, obj, oname='', info=None, detail_level=0):
730 """Compute a dict with detailed information about an object.
734 """Compute a dict with detailed information about an object.
731
735
732 Optional arguments:
736 Optional arguments:
733
737
734 - oname: name of the variable pointing to the object.
738 - oname: name of the variable pointing to the object.
735
739
736 - info: a structure with some information fields which may have been
740 - info: a structure with some information fields which may have been
737 precomputed already.
741 precomputed already.
738
742
739 - detail_level: if set to 1, more information is given.
743 - detail_level: if set to 1, more information is given.
740 """
744 """
741
745
742 obj_type = type(obj)
746 obj_type = type(obj)
743
747
744 if info is None:
748 if info is None:
745 ismagic = 0
749 ismagic = 0
746 isalias = 0
750 isalias = 0
747 ospace = ''
751 ospace = ''
748 else:
752 else:
749 ismagic = info.ismagic
753 ismagic = info.ismagic
750 isalias = info.isalias
754 isalias = info.isalias
751 ospace = info.namespace
755 ospace = info.namespace
752
756
753 # Get docstring, special-casing aliases:
757 # Get docstring, special-casing aliases:
754 if isalias:
758 if isalias:
755 if not callable(obj):
759 if not callable(obj):
756 try:
760 try:
757 ds = "Alias to the system command:\n %s" % obj[1]
761 ds = "Alias to the system command:\n %s" % obj[1]
758 except:
762 except:
759 ds = "Alias: " + str(obj)
763 ds = "Alias: " + str(obj)
760 else:
764 else:
761 ds = "Alias to " + str(obj)
765 ds = "Alias to " + str(obj)
762 if obj.__doc__:
766 if obj.__doc__:
763 ds += "\nDocstring:\n" + obj.__doc__
767 ds += "\nDocstring:\n" + obj.__doc__
764 else:
768 else:
765 ds = getdoc(obj)
769 ds = getdoc(obj)
766 if ds is None:
770 if ds is None:
767 ds = '<no docstring>'
771 ds = '<no docstring>'
768
772
769 # store output in a dict, we initialize it here and fill it as we go
773 # store output in a dict, we initialize it here and fill it as we go
770 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
774 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
771
775
772 string_max = 200 # max size of strings to show (snipped if longer)
776 string_max = 200 # max size of strings to show (snipped if longer)
773 shalf = int((string_max - 5) / 2)
777 shalf = int((string_max - 5) / 2)
774
778
775 if ismagic:
779 if ismagic:
776 obj_type_name = 'Magic function'
780 obj_type_name = 'Magic function'
777 elif isalias:
781 elif isalias:
778 obj_type_name = 'System alias'
782 obj_type_name = 'System alias'
779 else:
783 else:
780 obj_type_name = obj_type.__name__
784 obj_type_name = obj_type.__name__
781 out['type_name'] = obj_type_name
785 out['type_name'] = obj_type_name
782
786
783 try:
787 try:
784 bclass = obj.__class__
788 bclass = obj.__class__
785 out['base_class'] = str(bclass)
789 out['base_class'] = str(bclass)
786 except: pass
790 except: pass
787
791
788 # String form, but snip if too long in ? form (full in ??)
792 # String form, but snip if too long in ? form (full in ??)
789 if detail_level >= self.str_detail_level:
793 if detail_level >= self.str_detail_level:
790 try:
794 try:
791 ostr = str(obj)
795 ostr = str(obj)
792 str_head = 'string_form'
796 str_head = 'string_form'
793 if not detail_level and len(ostr)>string_max:
797 if not detail_level and len(ostr)>string_max:
794 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
798 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
795 ostr = ("\n" + " " * len(str_head.expandtabs())).\
799 ostr = ("\n" + " " * len(str_head.expandtabs())).\
796 join(q.strip() for q in ostr.split("\n"))
800 join(q.strip() for q in ostr.split("\n"))
797 out[str_head] = ostr
801 out[str_head] = ostr
798 except:
802 except:
799 pass
803 pass
800
804
801 if ospace:
805 if ospace:
802 out['namespace'] = ospace
806 out['namespace'] = ospace
803
807
804 # Length (for strings and lists)
808 # Length (for strings and lists)
805 try:
809 try:
806 out['length'] = str(len(obj))
810 out['length'] = str(len(obj))
807 except: pass
811 except: pass
808
812
809 # Filename where object was defined
813 # Filename where object was defined
810 binary_file = False
814 binary_file = False
811 fname = find_file(obj)
815 fname = find_file(obj)
812 if fname is None:
816 if fname is None:
813 # if anything goes wrong, we don't want to show source, so it's as
817 # if anything goes wrong, we don't want to show source, so it's as
814 # if the file was binary
818 # if the file was binary
815 binary_file = True
819 binary_file = True
816 else:
820 else:
817 if fname.endswith(('.so', '.dll', '.pyd')):
821 if fname.endswith(('.so', '.dll', '.pyd')):
818 binary_file = True
822 binary_file = True
819 elif fname.endswith('<string>'):
823 elif fname.endswith('<string>'):
820 fname = 'Dynamically generated function. No source code available.'
824 fname = 'Dynamically generated function. No source code available.'
821 out['file'] = compress_user(fname)
825 out['file'] = compress_user(fname)
822
826
823 # Original source code for a callable, class or property.
827 # Original source code for a callable, class or property.
824 if detail_level:
828 if detail_level:
825 # Flush the source cache because inspect can return out-of-date
829 # Flush the source cache because inspect can return out-of-date
826 # source
830 # source
827 linecache.checkcache()
831 linecache.checkcache()
828 try:
832 try:
829 if isinstance(obj, property) or not binary_file:
833 if isinstance(obj, property) or not binary_file:
830 src = getsource(obj, oname)
834 src = getsource(obj, oname)
831 if src is not None:
835 if src is not None:
832 src = src.rstrip()
836 src = src.rstrip()
833 out['source'] = src
837 out['source'] = src
834
838
835 except Exception:
839 except Exception:
836 pass
840 pass
837
841
838 # Add docstring only if no source is to be shown (avoid repetitions).
842 # Add docstring only if no source is to be shown (avoid repetitions).
839 if ds and out.get('source', None) is None:
843 if ds and out.get('source', None) is None:
840 out['docstring'] = ds
844 out['docstring'] = ds
841
845
842 # Constructor docstring for classes
846 # Constructor docstring for classes
843 if inspect.isclass(obj):
847 if inspect.isclass(obj):
844 out['isclass'] = True
848 out['isclass'] = True
845
849
846 # get the init signature:
850 # get the init signature:
847 try:
851 try:
848 init_def = self._getdef(obj, oname)
852 init_def = self._getdef(obj, oname)
849 except AttributeError:
853 except AttributeError:
850 init_def = None
854 init_def = None
851
855
852 # get the __init__ docstring
856 # get the __init__ docstring
853 try:
857 try:
854 obj_init = obj.__init__
858 obj_init = obj.__init__
855 except AttributeError:
859 except AttributeError:
856 init_ds = None
860 init_ds = None
857 else:
861 else:
858 if init_def is None:
862 if init_def is None:
859 # Get signature from init if top-level sig failed.
863 # Get signature from init if top-level sig failed.
860 # Can happen for built-in types (list, etc.).
864 # Can happen for built-in types (list, etc.).
861 try:
865 try:
862 init_def = self._getdef(obj_init, oname)
866 init_def = self._getdef(obj_init, oname)
863 except AttributeError:
867 except AttributeError:
864 pass
868 pass
865 init_ds = getdoc(obj_init)
869 init_ds = getdoc(obj_init)
866 # Skip Python's auto-generated docstrings
870 # Skip Python's auto-generated docstrings
867 if init_ds == _object_init_docstring:
871 if init_ds == _object_init_docstring:
868 init_ds = None
872 init_ds = None
869
873
870 if init_def:
874 if init_def:
871 out['init_definition'] = init_def
875 out['init_definition'] = init_def
872
876
873 if init_ds:
877 if init_ds:
874 out['init_docstring'] = init_ds
878 out['init_docstring'] = init_ds
875
879
876 # and class docstring for instances:
880 # and class docstring for instances:
877 else:
881 else:
878 # reconstruct the function definition and print it:
882 # reconstruct the function definition and print it:
879 defln = self._getdef(obj, oname)
883 defln = self._getdef(obj, oname)
880 if defln:
884 if defln:
881 out['definition'] = defln
885 out['definition'] = defln
882
886
883 # First, check whether the instance docstring is identical to the
887 # First, check whether the instance docstring is identical to the
884 # class one, and print it separately if they don't coincide. In
888 # class one, and print it separately if they don't coincide. In
885 # most cases they will, but it's nice to print all the info for
889 # most cases they will, but it's nice to print all the info for
886 # objects which use instance-customized docstrings.
890 # objects which use instance-customized docstrings.
887 if ds:
891 if ds:
888 try:
892 try:
889 cls = getattr(obj,'__class__')
893 cls = getattr(obj,'__class__')
890 except:
894 except:
891 class_ds = None
895 class_ds = None
892 else:
896 else:
893 class_ds = getdoc(cls)
897 class_ds = getdoc(cls)
894 # Skip Python's auto-generated docstrings
898 # Skip Python's auto-generated docstrings
895 if class_ds in _builtin_type_docstrings:
899 if class_ds in _builtin_type_docstrings:
896 class_ds = None
900 class_ds = None
897 if class_ds and ds != class_ds:
901 if class_ds and ds != class_ds:
898 out['class_docstring'] = class_ds
902 out['class_docstring'] = class_ds
899
903
900 # Next, try to show constructor docstrings
904 # Next, try to show constructor docstrings
901 try:
905 try:
902 init_ds = getdoc(obj.__init__)
906 init_ds = getdoc(obj.__init__)
903 # Skip Python's auto-generated docstrings
907 # Skip Python's auto-generated docstrings
904 if init_ds == _object_init_docstring:
908 if init_ds == _object_init_docstring:
905 init_ds = None
909 init_ds = None
906 except AttributeError:
910 except AttributeError:
907 init_ds = None
911 init_ds = None
908 if init_ds:
912 if init_ds:
909 out['init_docstring'] = init_ds
913 out['init_docstring'] = init_ds
910
914
911 # Call form docstring for callable instances
915 # Call form docstring for callable instances
912 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
916 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
913 call_def = self._getdef(obj.__call__, oname)
917 call_def = self._getdef(obj.__call__, oname)
914 if call_def and (call_def != out.get('definition')):
918 if call_def and (call_def != out.get('definition')):
915 # it may never be the case that call def and definition differ,
919 # it may never be the case that call def and definition differ,
916 # but don't include the same signature twice
920 # but don't include the same signature twice
917 out['call_def'] = call_def
921 out['call_def'] = call_def
918 call_ds = getdoc(obj.__call__)
922 call_ds = getdoc(obj.__call__)
919 # Skip Python's auto-generated docstrings
923 # Skip Python's auto-generated docstrings
920 if call_ds == _func_call_docstring:
924 if call_ds == _func_call_docstring:
921 call_ds = None
925 call_ds = None
922 if call_ds:
926 if call_ds:
923 out['call_docstring'] = call_ds
927 out['call_docstring'] = call_ds
924
928
925 # Compute the object's argspec as a callable. The key is to decide
929 # Compute the object's argspec as a callable. The key is to decide
926 # whether to pull it from the object itself, from its __init__ or
930 # whether to pull it from the object itself, from its __init__ or
927 # from its __call__ method.
931 # from its __call__ method.
928
932
929 if inspect.isclass(obj):
933 if inspect.isclass(obj):
930 # Old-style classes need not have an __init__
934 # Old-style classes need not have an __init__
931 callable_obj = getattr(obj, "__init__", None)
935 callable_obj = getattr(obj, "__init__", None)
932 elif callable(obj):
936 elif callable(obj):
933 callable_obj = obj
937 callable_obj = obj
934 else:
938 else:
935 callable_obj = None
939 callable_obj = None
936
940
937 if callable_obj is not None:
941 if callable_obj is not None:
938 try:
942 try:
939 argspec = getargspec(callable_obj)
943 argspec = getargspec(callable_obj)
940 except (TypeError, AttributeError):
944 except (TypeError, AttributeError):
941 # For extensions/builtins we can't retrieve the argspec
945 # For extensions/builtins we can't retrieve the argspec
942 pass
946 pass
943 else:
947 else:
944 # named tuples' _asdict() method returns an OrderedDict, but we
948 # named tuples' _asdict() method returns an OrderedDict, but we
945 # we want a normal
949 # we want a normal
946 out['argspec'] = argspec_dict = dict(argspec._asdict())
950 out['argspec'] = argspec_dict = dict(argspec._asdict())
947 # We called this varkw before argspec became a named tuple.
951 # We called this varkw before argspec became a named tuple.
948 # With getfullargspec it's also called varkw.
952 # With getfullargspec it's also called varkw.
949 if 'varkw' not in argspec_dict:
953 if 'varkw' not in argspec_dict:
950 argspec_dict['varkw'] = argspec_dict.pop('keywords')
954 argspec_dict['varkw'] = argspec_dict.pop('keywords')
951
955
952 return object_info(**out)
956 return object_info(**out)
953
957
954 def psearch(self,pattern,ns_table,ns_search=[],
958 def psearch(self,pattern,ns_table,ns_search=[],
955 ignore_case=False,show_all=False):
959 ignore_case=False,show_all=False):
956 """Search namespaces with wildcards for objects.
960 """Search namespaces with wildcards for objects.
957
961
958 Arguments:
962 Arguments:
959
963
960 - pattern: string containing shell-like wildcards to use in namespace
964 - pattern: string containing shell-like wildcards to use in namespace
961 searches and optionally a type specification to narrow the search to
965 searches and optionally a type specification to narrow the search to
962 objects of that type.
966 objects of that type.
963
967
964 - ns_table: dict of name->namespaces for search.
968 - ns_table: dict of name->namespaces for search.
965
969
966 Optional arguments:
970 Optional arguments:
967
971
968 - ns_search: list of namespace names to include in search.
972 - ns_search: list of namespace names to include in search.
969
973
970 - ignore_case(False): make the search case-insensitive.
974 - ignore_case(False): make the search case-insensitive.
971
975
972 - show_all(False): show all names, including those starting with
976 - show_all(False): show all names, including those starting with
973 underscores.
977 underscores.
974 """
978 """
975 #print 'ps pattern:<%r>' % pattern # dbg
979 #print 'ps pattern:<%r>' % pattern # dbg
976
980
977 # defaults
981 # defaults
978 type_pattern = 'all'
982 type_pattern = 'all'
979 filter = ''
983 filter = ''
980
984
981 cmds = pattern.split()
985 cmds = pattern.split()
982 len_cmds = len(cmds)
986 len_cmds = len(cmds)
983 if len_cmds == 1:
987 if len_cmds == 1:
984 # Only filter pattern given
988 # Only filter pattern given
985 filter = cmds[0]
989 filter = cmds[0]
986 elif len_cmds == 2:
990 elif len_cmds == 2:
987 # Both filter and type specified
991 # Both filter and type specified
988 filter,type_pattern = cmds
992 filter,type_pattern = cmds
989 else:
993 else:
990 raise ValueError('invalid argument string for psearch: <%s>' %
994 raise ValueError('invalid argument string for psearch: <%s>' %
991 pattern)
995 pattern)
992
996
993 # filter search namespaces
997 # filter search namespaces
994 for name in ns_search:
998 for name in ns_search:
995 if name not in ns_table:
999 if name not in ns_table:
996 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1000 raise ValueError('invalid namespace <%s>. Valid names: %s' %
997 (name,ns_table.keys()))
1001 (name,ns_table.keys()))
998
1002
999 #print 'type_pattern:',type_pattern # dbg
1003 #print 'type_pattern:',type_pattern # dbg
1000 search_result, namespaces_seen = set(), set()
1004 search_result, namespaces_seen = set(), set()
1001 for ns_name in ns_search:
1005 for ns_name in ns_search:
1002 ns = ns_table[ns_name]
1006 ns = ns_table[ns_name]
1003 # Normally, locals and globals are the same, so we just check one.
1007 # Normally, locals and globals are the same, so we just check one.
1004 if id(ns) in namespaces_seen:
1008 if id(ns) in namespaces_seen:
1005 continue
1009 continue
1006 namespaces_seen.add(id(ns))
1010 namespaces_seen.add(id(ns))
1007 tmp_res = list_namespace(ns, type_pattern, filter,
1011 tmp_res = list_namespace(ns, type_pattern, filter,
1008 ignore_case=ignore_case, show_all=show_all)
1012 ignore_case=ignore_case, show_all=show_all)
1009 search_result.update(tmp_res)
1013 search_result.update(tmp_res)
1010
1014
1011 page.page('\n'.join(sorted(search_result)))
1015 page.page('\n'.join(sorted(search_result)))
@@ -1,512 +1,517 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Defines a variety of Pygments lexers for highlighting IPython code.
3 Defines a variety of Pygments lexers for highlighting IPython code.
4
4
5 This includes:
5 This includes:
6
6
7 IPythonLexer, IPython3Lexer
7 IPythonLexer, IPython3Lexer
8 Lexers for pure IPython (python + magic/shell commands)
8 Lexers for pure IPython (python + magic/shell commands)
9
9
10 IPythonPartialTracebackLexer, IPythonTracebackLexer
10 IPythonPartialTracebackLexer, IPythonTracebackLexer
11 Supports 2.x and 3.x via keyword `python3`. The partial traceback
11 Supports 2.x and 3.x via keyword `python3`. The partial traceback
12 lexer reads everything but the Python code appearing in a traceback.
12 lexer reads everything but the Python code appearing in a traceback.
13 The full lexer combines the partial lexer with an IPython lexer.
13 The full lexer combines the partial lexer with an IPython lexer.
14
14
15 IPythonConsoleLexer
15 IPythonConsoleLexer
16 A lexer for IPython console sessions, with support for tracebacks.
16 A lexer for IPython console sessions, with support for tracebacks.
17
17
18 IPyLexer
18 IPyLexer
19 A friendly lexer which examines the first line of text and from it,
19 A friendly lexer which examines the first line of text and from it,
20 decides whether to use an IPython lexer or an IPython console lexer.
20 decides whether to use an IPython lexer or an IPython console lexer.
21 This is probably the only lexer that needs to be explicitly added
21 This is probably the only lexer that needs to be explicitly added
22 to Pygments.
22 to Pygments.
23
23
24 """
24 """
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Copyright (c) 2013, the IPython Development Team.
26 # Copyright (c) 2013, the IPython Development Team.
27 #
27 #
28 # Distributed under the terms of the Modified BSD License.
28 # Distributed under the terms of the Modified BSD License.
29 #
29 #
30 # The full license is in the file COPYING.txt, distributed with this software.
30 # The full license is in the file COPYING.txt, distributed with this software.
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 # Standard library
33 # Standard library
34 import re
34 import re
35
35
36 # Third party
36 # Third party
37 from pygments.lexers import BashLexer, PythonLexer, Python3Lexer
37 from pygments.lexers import BashLexer, Python3Lexer
38 try:
39 # PythonLexer was renamed to Python2Lexer in pygments 2.5
40 from pygments.lexers import Python2Lexer
41 except ImportError:
42 from pygments.lexers import PythonLexer as Python2Lexer
38 from pygments.lexer import (
43 from pygments.lexer import (
39 Lexer, DelegatingLexer, RegexLexer, do_insertions, bygroups, using,
44 Lexer, DelegatingLexer, RegexLexer, do_insertions, bygroups, using,
40 )
45 )
41 from pygments.token import (
46 from pygments.token import (
42 Generic, Keyword, Literal, Name, Operator, Other, Text, Error,
47 Generic, Keyword, Literal, Name, Operator, Other, Text, Error,
43 )
48 )
44 from pygments.util import get_bool_opt
49 from pygments.util import get_bool_opt
45
50
46 # Local
51 # Local
47
52
48 line_re = re.compile('.*?\n')
53 line_re = re.compile('.*?\n')
49
54
50 __all__ = ['build_ipy_lexer', 'IPython3Lexer', 'IPythonLexer',
55 __all__ = ['build_ipy_lexer', 'IPython3Lexer', 'IPythonLexer',
51 'IPythonPartialTracebackLexer', 'IPythonTracebackLexer',
56 'IPythonPartialTracebackLexer', 'IPythonTracebackLexer',
52 'IPythonConsoleLexer', 'IPyLexer']
57 'IPythonConsoleLexer', 'IPyLexer']
53
58
54 ipython_tokens = [
59 ipython_tokens = [
55 (r"(?s)(\s*)(%%)(\w+)(.*)", bygroups(Text, Operator, Keyword, Text)),
60 (r"(?s)(\s*)(%%)(\w+)(.*)", bygroups(Text, Operator, Keyword, Text)),
56 (r'(?s)(^\s*)(%%!)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(BashLexer))),
61 (r'(?s)(^\s*)(%%!)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(BashLexer))),
57 (r"(%%?)(\w+)(\?\??)$", bygroups(Operator, Keyword, Operator)),
62 (r"(%%?)(\w+)(\?\??)$", bygroups(Operator, Keyword, Operator)),
58 (r"\b(\?\??)(\s*)$", bygroups(Operator, Text)),
63 (r"\b(\?\??)(\s*)$", bygroups(Operator, Text)),
59 (r'(%)(sx|sc|system)(.*)(\n)', bygroups(Operator, Keyword,
64 (r'(%)(sx|sc|system)(.*)(\n)', bygroups(Operator, Keyword,
60 using(BashLexer), Text)),
65 using(BashLexer), Text)),
61 (r'(%)(\w+)(.*\n)', bygroups(Operator, Keyword, Text)),
66 (r'(%)(\w+)(.*\n)', bygroups(Operator, Keyword, Text)),
62 (r'^(!!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
67 (r'^(!!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
63 (r'(!)(?!=)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
68 (r'(!)(?!=)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
64 (r'^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)', bygroups(Text, Operator, Text)),
69 (r'^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)', bygroups(Text, Operator, Text)),
65 (r'(\s*%{0,2}[\w\.\*]*)(\?\??)(\s*)$', bygroups(Text, Operator, Text)),
70 (r'(\s*%{0,2}[\w\.\*]*)(\?\??)(\s*)$', bygroups(Text, Operator, Text)),
66 ]
71 ]
67
72
68 def build_ipy_lexer(python3):
73 def build_ipy_lexer(python3):
69 """Builds IPython lexers depending on the value of `python3`.
74 """Builds IPython lexers depending on the value of `python3`.
70
75
71 The lexer inherits from an appropriate Python lexer and then adds
76 The lexer inherits from an appropriate Python lexer and then adds
72 information about IPython specific keywords (i.e. magic commands,
77 information about IPython specific keywords (i.e. magic commands,
73 shell commands, etc.)
78 shell commands, etc.)
74
79
75 Parameters
80 Parameters
76 ----------
81 ----------
77 python3 : bool
82 python3 : bool
78 If `True`, then build an IPython lexer from a Python 3 lexer.
83 If `True`, then build an IPython lexer from a Python 3 lexer.
79
84
80 """
85 """
81 # It would be nice to have a single IPython lexer class which takes
86 # It would be nice to have a single IPython lexer class which takes
82 # a boolean `python3`. But since there are two Python lexer classes,
87 # a boolean `python3`. But since there are two Python lexer classes,
83 # we will also have two IPython lexer classes.
88 # we will also have two IPython lexer classes.
84 if python3:
89 if python3:
85 PyLexer = Python3Lexer
90 PyLexer = Python3Lexer
86 name = 'IPython3'
91 name = 'IPython3'
87 aliases = ['ipython3']
92 aliases = ['ipython3']
88 doc = """IPython3 Lexer"""
93 doc = """IPython3 Lexer"""
89 else:
94 else:
90 PyLexer = PythonLexer
95 PyLexer = Python2Lexer
91 name = 'IPython'
96 name = 'IPython'
92 aliases = ['ipython2', 'ipython']
97 aliases = ['ipython2', 'ipython']
93 doc = """IPython Lexer"""
98 doc = """IPython Lexer"""
94
99
95 tokens = PyLexer.tokens.copy()
100 tokens = PyLexer.tokens.copy()
96 tokens['root'] = ipython_tokens + tokens['root']
101 tokens['root'] = ipython_tokens + tokens['root']
97
102
98 attrs = {'name': name, 'aliases': aliases, 'filenames': [],
103 attrs = {'name': name, 'aliases': aliases, 'filenames': [],
99 '__doc__': doc, 'tokens': tokens}
104 '__doc__': doc, 'tokens': tokens}
100
105
101 return type(name, (PyLexer,), attrs)
106 return type(name, (PyLexer,), attrs)
102
107
103
108
104 IPython3Lexer = build_ipy_lexer(python3=True)
109 IPython3Lexer = build_ipy_lexer(python3=True)
105 IPythonLexer = build_ipy_lexer(python3=False)
110 IPythonLexer = build_ipy_lexer(python3=False)
106
111
107
112
108 class IPythonPartialTracebackLexer(RegexLexer):
113 class IPythonPartialTracebackLexer(RegexLexer):
109 """
114 """
110 Partial lexer for IPython tracebacks.
115 Partial lexer for IPython tracebacks.
111
116
112 Handles all the non-python output. This works for both Python 2.x and 3.x.
117 Handles all the non-python output. This works for both Python 2.x and 3.x.
113
118
114 """
119 """
115 name = 'IPython Partial Traceback'
120 name = 'IPython Partial Traceback'
116
121
117 tokens = {
122 tokens = {
118 'root': [
123 'root': [
119 # Tracebacks for syntax errors have a different style.
124 # Tracebacks for syntax errors have a different style.
120 # For both types of tracebacks, we mark the first line with
125 # For both types of tracebacks, we mark the first line with
121 # Generic.Traceback. For syntax errors, we mark the filename
126 # Generic.Traceback. For syntax errors, we mark the filename
122 # as we mark the filenames for non-syntax tracebacks.
127 # as we mark the filenames for non-syntax tracebacks.
123 #
128 #
124 # These two regexps define how IPythonConsoleLexer finds a
129 # These two regexps define how IPythonConsoleLexer finds a
125 # traceback.
130 # traceback.
126 #
131 #
127 ## Non-syntax traceback
132 ## Non-syntax traceback
128 (r'^(\^C)?(-+\n)', bygroups(Error, Generic.Traceback)),
133 (r'^(\^C)?(-+\n)', bygroups(Error, Generic.Traceback)),
129 ## Syntax traceback
134 ## Syntax traceback
130 (r'^( File)(.*)(, line )(\d+\n)',
135 (r'^( File)(.*)(, line )(\d+\n)',
131 bygroups(Generic.Traceback, Name.Namespace,
136 bygroups(Generic.Traceback, Name.Namespace,
132 Generic.Traceback, Literal.Number.Integer)),
137 Generic.Traceback, Literal.Number.Integer)),
133
138
134 # (Exception Identifier)(Whitespace)(Traceback Message)
139 # (Exception Identifier)(Whitespace)(Traceback Message)
135 (r'(?u)(^[^\d\W]\w*)(\s*)(Traceback.*?\n)',
140 (r'(?u)(^[^\d\W]\w*)(\s*)(Traceback.*?\n)',
136 bygroups(Name.Exception, Generic.Whitespace, Text)),
141 bygroups(Name.Exception, Generic.Whitespace, Text)),
137 # (Module/Filename)(Text)(Callee)(Function Signature)
142 # (Module/Filename)(Text)(Callee)(Function Signature)
138 # Better options for callee and function signature?
143 # Better options for callee and function signature?
139 (r'(.*)( in )(.*)(\(.*\)\n)',
144 (r'(.*)( in )(.*)(\(.*\)\n)',
140 bygroups(Name.Namespace, Text, Name.Entity, Name.Tag)),
145 bygroups(Name.Namespace, Text, Name.Entity, Name.Tag)),
141 # Regular line: (Whitespace)(Line Number)(Python Code)
146 # Regular line: (Whitespace)(Line Number)(Python Code)
142 (r'(\s*?)(\d+)(.*?\n)',
147 (r'(\s*?)(\d+)(.*?\n)',
143 bygroups(Generic.Whitespace, Literal.Number.Integer, Other)),
148 bygroups(Generic.Whitespace, Literal.Number.Integer, Other)),
144 # Emphasized line: (Arrow)(Line Number)(Python Code)
149 # Emphasized line: (Arrow)(Line Number)(Python Code)
145 # Using Exception token so arrow color matches the Exception.
150 # Using Exception token so arrow color matches the Exception.
146 (r'(-*>?\s?)(\d+)(.*?\n)',
151 (r'(-*>?\s?)(\d+)(.*?\n)',
147 bygroups(Name.Exception, Literal.Number.Integer, Other)),
152 bygroups(Name.Exception, Literal.Number.Integer, Other)),
148 # (Exception Identifier)(Message)
153 # (Exception Identifier)(Message)
149 (r'(?u)(^[^\d\W]\w*)(:.*?\n)',
154 (r'(?u)(^[^\d\W]\w*)(:.*?\n)',
150 bygroups(Name.Exception, Text)),
155 bygroups(Name.Exception, Text)),
151 # Tag everything else as Other, will be handled later.
156 # Tag everything else as Other, will be handled later.
152 (r'.*\n', Other),
157 (r'.*\n', Other),
153 ],
158 ],
154 }
159 }
155
160
156
161
157 class IPythonTracebackLexer(DelegatingLexer):
162 class IPythonTracebackLexer(DelegatingLexer):
158 """
163 """
159 IPython traceback lexer.
164 IPython traceback lexer.
160
165
161 For doctests, the tracebacks can be snipped as much as desired with the
166 For doctests, the tracebacks can be snipped as much as desired with the
162 exception to the lines that designate a traceback. For non-syntax error
167 exception to the lines that designate a traceback. For non-syntax error
163 tracebacks, this is the line of hyphens. For syntax error tracebacks,
168 tracebacks, this is the line of hyphens. For syntax error tracebacks,
164 this is the line which lists the File and line number.
169 this is the line which lists the File and line number.
165
170
166 """
171 """
167 # The lexer inherits from DelegatingLexer. The "root" lexer is an
172 # The lexer inherits from DelegatingLexer. The "root" lexer is an
168 # appropriate IPython lexer, which depends on the value of the boolean
173 # appropriate IPython lexer, which depends on the value of the boolean
169 # `python3`. First, we parse with the partial IPython traceback lexer.
174 # `python3`. First, we parse with the partial IPython traceback lexer.
170 # Then, any code marked with the "Other" token is delegated to the root
175 # Then, any code marked with the "Other" token is delegated to the root
171 # lexer.
176 # lexer.
172 #
177 #
173 name = 'IPython Traceback'
178 name = 'IPython Traceback'
174 aliases = ['ipythontb']
179 aliases = ['ipythontb']
175
180
176 def __init__(self, **options):
181 def __init__(self, **options):
177 self.python3 = get_bool_opt(options, 'python3', False)
182 self.python3 = get_bool_opt(options, 'python3', False)
178 if self.python3:
183 if self.python3:
179 self.aliases = ['ipython3tb']
184 self.aliases = ['ipython3tb']
180 else:
185 else:
181 self.aliases = ['ipython2tb', 'ipythontb']
186 self.aliases = ['ipython2tb', 'ipythontb']
182
187
183 if self.python3:
188 if self.python3:
184 IPyLexer = IPython3Lexer
189 IPyLexer = IPython3Lexer
185 else:
190 else:
186 IPyLexer = IPythonLexer
191 IPyLexer = IPythonLexer
187
192
188 DelegatingLexer.__init__(self, IPyLexer,
193 DelegatingLexer.__init__(self, IPyLexer,
189 IPythonPartialTracebackLexer, **options)
194 IPythonPartialTracebackLexer, **options)
190
195
191 class IPythonConsoleLexer(Lexer):
196 class IPythonConsoleLexer(Lexer):
192 """
197 """
193 An IPython console lexer for IPython code-blocks and doctests, such as:
198 An IPython console lexer for IPython code-blocks and doctests, such as:
194
199
195 .. code-block:: rst
200 .. code-block:: rst
196
201
197 .. code-block:: ipythonconsole
202 .. code-block:: ipythonconsole
198
203
199 In [1]: a = 'foo'
204 In [1]: a = 'foo'
200
205
201 In [2]: a
206 In [2]: a
202 Out[2]: 'foo'
207 Out[2]: 'foo'
203
208
204 In [3]: print a
209 In [3]: print a
205 foo
210 foo
206
211
207 In [4]: 1 / 0
212 In [4]: 1 / 0
208
213
209
214
210 Support is also provided for IPython exceptions:
215 Support is also provided for IPython exceptions:
211
216
212 .. code-block:: rst
217 .. code-block:: rst
213
218
214 .. code-block:: ipythonconsole
219 .. code-block:: ipythonconsole
215
220
216 In [1]: raise Exception
221 In [1]: raise Exception
217
222
218 ---------------------------------------------------------------------------
223 ---------------------------------------------------------------------------
219 Exception Traceback (most recent call last)
224 Exception Traceback (most recent call last)
220 <ipython-input-1-fca2ab0ca76b> in <module>()
225 <ipython-input-1-fca2ab0ca76b> in <module>()
221 ----> 1 raise Exception
226 ----> 1 raise Exception
222
227
223 Exception:
228 Exception:
224
229
225 """
230 """
226 name = 'IPython console session'
231 name = 'IPython console session'
227 aliases = ['ipythonconsole']
232 aliases = ['ipythonconsole']
228 mimetypes = ['text/x-ipython-console']
233 mimetypes = ['text/x-ipython-console']
229
234
230 # The regexps used to determine what is input and what is output.
235 # The regexps used to determine what is input and what is output.
231 # The default prompts for IPython are:
236 # The default prompts for IPython are:
232 #
237 #
233 # in = 'In [#]: '
238 # in = 'In [#]: '
234 # continuation = ' .D.: '
239 # continuation = ' .D.: '
235 # template = 'Out[#]: '
240 # template = 'Out[#]: '
236 #
241 #
237 # Where '#' is the 'prompt number' or 'execution count' and 'D'
242 # Where '#' is the 'prompt number' or 'execution count' and 'D'
238 # D is a number of dots matching the width of the execution count
243 # D is a number of dots matching the width of the execution count
239 #
244 #
240 in1_regex = r'In \[[0-9]+\]: '
245 in1_regex = r'In \[[0-9]+\]: '
241 in2_regex = r' \.\.+\.: '
246 in2_regex = r' \.\.+\.: '
242 out_regex = r'Out\[[0-9]+\]: '
247 out_regex = r'Out\[[0-9]+\]: '
243
248
244 #: The regex to determine when a traceback starts.
249 #: The regex to determine when a traceback starts.
245 ipytb_start = re.compile(r'^(\^C)?(-+\n)|^( File)(.*)(, line )(\d+\n)')
250 ipytb_start = re.compile(r'^(\^C)?(-+\n)|^( File)(.*)(, line )(\d+\n)')
246
251
247 def __init__(self, **options):
252 def __init__(self, **options):
248 """Initialize the IPython console lexer.
253 """Initialize the IPython console lexer.
249
254
250 Parameters
255 Parameters
251 ----------
256 ----------
252 python3 : bool
257 python3 : bool
253 If `True`, then the console inputs are parsed using a Python 3
258 If `True`, then the console inputs are parsed using a Python 3
254 lexer. Otherwise, they are parsed using a Python 2 lexer.
259 lexer. Otherwise, they are parsed using a Python 2 lexer.
255 in1_regex : RegexObject
260 in1_regex : RegexObject
256 The compiled regular expression used to detect the start
261 The compiled regular expression used to detect the start
257 of inputs. Although the IPython configuration setting may have a
262 of inputs. Although the IPython configuration setting may have a
258 trailing whitespace, do not include it in the regex. If `None`,
263 trailing whitespace, do not include it in the regex. If `None`,
259 then the default input prompt is assumed.
264 then the default input prompt is assumed.
260 in2_regex : RegexObject
265 in2_regex : RegexObject
261 The compiled regular expression used to detect the continuation
266 The compiled regular expression used to detect the continuation
262 of inputs. Although the IPython configuration setting may have a
267 of inputs. Although the IPython configuration setting may have a
263 trailing whitespace, do not include it in the regex. If `None`,
268 trailing whitespace, do not include it in the regex. If `None`,
264 then the default input prompt is assumed.
269 then the default input prompt is assumed.
265 out_regex : RegexObject
270 out_regex : RegexObject
266 The compiled regular expression used to detect outputs. If `None`,
271 The compiled regular expression used to detect outputs. If `None`,
267 then the default output prompt is assumed.
272 then the default output prompt is assumed.
268
273
269 """
274 """
270 self.python3 = get_bool_opt(options, 'python3', False)
275 self.python3 = get_bool_opt(options, 'python3', False)
271 if self.python3:
276 if self.python3:
272 self.aliases = ['ipython3console']
277 self.aliases = ['ipython3console']
273 else:
278 else:
274 self.aliases = ['ipython2console', 'ipythonconsole']
279 self.aliases = ['ipython2console', 'ipythonconsole']
275
280
276 in1_regex = options.get('in1_regex', self.in1_regex)
281 in1_regex = options.get('in1_regex', self.in1_regex)
277 in2_regex = options.get('in2_regex', self.in2_regex)
282 in2_regex = options.get('in2_regex', self.in2_regex)
278 out_regex = options.get('out_regex', self.out_regex)
283 out_regex = options.get('out_regex', self.out_regex)
279
284
280 # So that we can work with input and output prompts which have been
285 # So that we can work with input and output prompts which have been
281 # rstrip'd (possibly by editors) we also need rstrip'd variants. If
286 # rstrip'd (possibly by editors) we also need rstrip'd variants. If
282 # we do not do this, then such prompts will be tagged as 'output'.
287 # we do not do this, then such prompts will be tagged as 'output'.
283 # The reason can't just use the rstrip'd variants instead is because
288 # The reason can't just use the rstrip'd variants instead is because
284 # we want any whitespace associated with the prompt to be inserted
289 # we want any whitespace associated with the prompt to be inserted
285 # with the token. This allows formatted code to be modified so as hide
290 # with the token. This allows formatted code to be modified so as hide
286 # the appearance of prompts, with the whitespace included. One example
291 # the appearance of prompts, with the whitespace included. One example
287 # use of this is in copybutton.js from the standard lib Python docs.
292 # use of this is in copybutton.js from the standard lib Python docs.
288 in1_regex_rstrip = in1_regex.rstrip() + '\n'
293 in1_regex_rstrip = in1_regex.rstrip() + '\n'
289 in2_regex_rstrip = in2_regex.rstrip() + '\n'
294 in2_regex_rstrip = in2_regex.rstrip() + '\n'
290 out_regex_rstrip = out_regex.rstrip() + '\n'
295 out_regex_rstrip = out_regex.rstrip() + '\n'
291
296
292 # Compile and save them all.
297 # Compile and save them all.
293 attrs = ['in1_regex', 'in2_regex', 'out_regex',
298 attrs = ['in1_regex', 'in2_regex', 'out_regex',
294 'in1_regex_rstrip', 'in2_regex_rstrip', 'out_regex_rstrip']
299 'in1_regex_rstrip', 'in2_regex_rstrip', 'out_regex_rstrip']
295 for attr in attrs:
300 for attr in attrs:
296 self.__setattr__(attr, re.compile(locals()[attr]))
301 self.__setattr__(attr, re.compile(locals()[attr]))
297
302
298 Lexer.__init__(self, **options)
303 Lexer.__init__(self, **options)
299
304
300 if self.python3:
305 if self.python3:
301 pylexer = IPython3Lexer
306 pylexer = IPython3Lexer
302 tblexer = IPythonTracebackLexer
307 tblexer = IPythonTracebackLexer
303 else:
308 else:
304 pylexer = IPythonLexer
309 pylexer = IPythonLexer
305 tblexer = IPythonTracebackLexer
310 tblexer = IPythonTracebackLexer
306
311
307 self.pylexer = pylexer(**options)
312 self.pylexer = pylexer(**options)
308 self.tblexer = tblexer(**options)
313 self.tblexer = tblexer(**options)
309
314
310 self.reset()
315 self.reset()
311
316
312 def reset(self):
317 def reset(self):
313 self.mode = 'output'
318 self.mode = 'output'
314 self.index = 0
319 self.index = 0
315 self.buffer = u''
320 self.buffer = u''
316 self.insertions = []
321 self.insertions = []
317
322
318 def buffered_tokens(self):
323 def buffered_tokens(self):
319 """
324 """
320 Generator of unprocessed tokens after doing insertions and before
325 Generator of unprocessed tokens after doing insertions and before
321 changing to a new state.
326 changing to a new state.
322
327
323 """
328 """
324 if self.mode == 'output':
329 if self.mode == 'output':
325 tokens = [(0, Generic.Output, self.buffer)]
330 tokens = [(0, Generic.Output, self.buffer)]
326 elif self.mode == 'input':
331 elif self.mode == 'input':
327 tokens = self.pylexer.get_tokens_unprocessed(self.buffer)
332 tokens = self.pylexer.get_tokens_unprocessed(self.buffer)
328 else: # traceback
333 else: # traceback
329 tokens = self.tblexer.get_tokens_unprocessed(self.buffer)
334 tokens = self.tblexer.get_tokens_unprocessed(self.buffer)
330
335
331 for i, t, v in do_insertions(self.insertions, tokens):
336 for i, t, v in do_insertions(self.insertions, tokens):
332 # All token indexes are relative to the buffer.
337 # All token indexes are relative to the buffer.
333 yield self.index + i, t, v
338 yield self.index + i, t, v
334
339
335 # Clear it all
340 # Clear it all
336 self.index += len(self.buffer)
341 self.index += len(self.buffer)
337 self.buffer = u''
342 self.buffer = u''
338 self.insertions = []
343 self.insertions = []
339
344
340 def get_mci(self, line):
345 def get_mci(self, line):
341 """
346 """
342 Parses the line and returns a 3-tuple: (mode, code, insertion).
347 Parses the line and returns a 3-tuple: (mode, code, insertion).
343
348
344 `mode` is the next mode (or state) of the lexer, and is always equal
349 `mode` is the next mode (or state) of the lexer, and is always equal
345 to 'input', 'output', or 'tb'.
350 to 'input', 'output', or 'tb'.
346
351
347 `code` is a portion of the line that should be added to the buffer
352 `code` is a portion of the line that should be added to the buffer
348 corresponding to the next mode and eventually lexed by another lexer.
353 corresponding to the next mode and eventually lexed by another lexer.
349 For example, `code` could be Python code if `mode` were 'input'.
354 For example, `code` could be Python code if `mode` were 'input'.
350
355
351 `insertion` is a 3-tuple (index, token, text) representing an
356 `insertion` is a 3-tuple (index, token, text) representing an
352 unprocessed "token" that will be inserted into the stream of tokens
357 unprocessed "token" that will be inserted into the stream of tokens
353 that are created from the buffer once we change modes. This is usually
358 that are created from the buffer once we change modes. This is usually
354 the input or output prompt.
359 the input or output prompt.
355
360
356 In general, the next mode depends on current mode and on the contents
361 In general, the next mode depends on current mode and on the contents
357 of `line`.
362 of `line`.
358
363
359 """
364 """
360 # To reduce the number of regex match checks, we have multiple
365 # To reduce the number of regex match checks, we have multiple
361 # 'if' blocks instead of 'if-elif' blocks.
366 # 'if' blocks instead of 'if-elif' blocks.
362
367
363 # Check for possible end of input
368 # Check for possible end of input
364 in2_match = self.in2_regex.match(line)
369 in2_match = self.in2_regex.match(line)
365 in2_match_rstrip = self.in2_regex_rstrip.match(line)
370 in2_match_rstrip = self.in2_regex_rstrip.match(line)
366 if (in2_match and in2_match.group().rstrip() == line.rstrip()) or \
371 if (in2_match and in2_match.group().rstrip() == line.rstrip()) or \
367 in2_match_rstrip:
372 in2_match_rstrip:
368 end_input = True
373 end_input = True
369 else:
374 else:
370 end_input = False
375 end_input = False
371 if end_input and self.mode != 'tb':
376 if end_input and self.mode != 'tb':
372 # Only look for an end of input when not in tb mode.
377 # Only look for an end of input when not in tb mode.
373 # An ellipsis could appear within the traceback.
378 # An ellipsis could appear within the traceback.
374 mode = 'output'
379 mode = 'output'
375 code = u''
380 code = u''
376 insertion = (0, Generic.Prompt, line)
381 insertion = (0, Generic.Prompt, line)
377 return mode, code, insertion
382 return mode, code, insertion
378
383
379 # Check for output prompt
384 # Check for output prompt
380 out_match = self.out_regex.match(line)
385 out_match = self.out_regex.match(line)
381 out_match_rstrip = self.out_regex_rstrip.match(line)
386 out_match_rstrip = self.out_regex_rstrip.match(line)
382 if out_match or out_match_rstrip:
387 if out_match or out_match_rstrip:
383 mode = 'output'
388 mode = 'output'
384 if out_match:
389 if out_match:
385 idx = out_match.end()
390 idx = out_match.end()
386 else:
391 else:
387 idx = out_match_rstrip.end()
392 idx = out_match_rstrip.end()
388 code = line[idx:]
393 code = line[idx:]
389 # Use the 'heading' token for output. We cannot use Generic.Error
394 # Use the 'heading' token for output. We cannot use Generic.Error
390 # since it would conflict with exceptions.
395 # since it would conflict with exceptions.
391 insertion = (0, Generic.Heading, line[:idx])
396 insertion = (0, Generic.Heading, line[:idx])
392 return mode, code, insertion
397 return mode, code, insertion
393
398
394
399
395 # Check for input or continuation prompt (non stripped version)
400 # Check for input or continuation prompt (non stripped version)
396 in1_match = self.in1_regex.match(line)
401 in1_match = self.in1_regex.match(line)
397 if in1_match or (in2_match and self.mode != 'tb'):
402 if in1_match or (in2_match and self.mode != 'tb'):
398 # New input or when not in tb, continued input.
403 # New input or when not in tb, continued input.
399 # We do not check for continued input when in tb since it is
404 # We do not check for continued input when in tb since it is
400 # allowable to replace a long stack with an ellipsis.
405 # allowable to replace a long stack with an ellipsis.
401 mode = 'input'
406 mode = 'input'
402 if in1_match:
407 if in1_match:
403 idx = in1_match.end()
408 idx = in1_match.end()
404 else: # in2_match
409 else: # in2_match
405 idx = in2_match.end()
410 idx = in2_match.end()
406 code = line[idx:]
411 code = line[idx:]
407 insertion = (0, Generic.Prompt, line[:idx])
412 insertion = (0, Generic.Prompt, line[:idx])
408 return mode, code, insertion
413 return mode, code, insertion
409
414
410 # Check for input or continuation prompt (stripped version)
415 # Check for input or continuation prompt (stripped version)
411 in1_match_rstrip = self.in1_regex_rstrip.match(line)
416 in1_match_rstrip = self.in1_regex_rstrip.match(line)
412 if in1_match_rstrip or (in2_match_rstrip and self.mode != 'tb'):
417 if in1_match_rstrip or (in2_match_rstrip and self.mode != 'tb'):
413 # New input or when not in tb, continued input.
418 # New input or when not in tb, continued input.
414 # We do not check for continued input when in tb since it is
419 # We do not check for continued input when in tb since it is
415 # allowable to replace a long stack with an ellipsis.
420 # allowable to replace a long stack with an ellipsis.
416 mode = 'input'
421 mode = 'input'
417 if in1_match_rstrip:
422 if in1_match_rstrip:
418 idx = in1_match_rstrip.end()
423 idx = in1_match_rstrip.end()
419 else: # in2_match
424 else: # in2_match
420 idx = in2_match_rstrip.end()
425 idx = in2_match_rstrip.end()
421 code = line[idx:]
426 code = line[idx:]
422 insertion = (0, Generic.Prompt, line[:idx])
427 insertion = (0, Generic.Prompt, line[:idx])
423 return mode, code, insertion
428 return mode, code, insertion
424
429
425 # Check for traceback
430 # Check for traceback
426 if self.ipytb_start.match(line):
431 if self.ipytb_start.match(line):
427 mode = 'tb'
432 mode = 'tb'
428 code = line
433 code = line
429 insertion = None
434 insertion = None
430 return mode, code, insertion
435 return mode, code, insertion
431
436
432 # All other stuff...
437 # All other stuff...
433 if self.mode in ('input', 'output'):
438 if self.mode in ('input', 'output'):
434 # We assume all other text is output. Multiline input that
439 # We assume all other text is output. Multiline input that
435 # does not use the continuation marker cannot be detected.
440 # does not use the continuation marker cannot be detected.
436 # For example, the 3 in the following is clearly output:
441 # For example, the 3 in the following is clearly output:
437 #
442 #
438 # In [1]: print 3
443 # In [1]: print 3
439 # 3
444 # 3
440 #
445 #
441 # But the following second line is part of the input:
446 # But the following second line is part of the input:
442 #
447 #
443 # In [2]: while True:
448 # In [2]: while True:
444 # print True
449 # print True
445 #
450 #
446 # In both cases, the 2nd line will be 'output'.
451 # In both cases, the 2nd line will be 'output'.
447 #
452 #
448 mode = 'output'
453 mode = 'output'
449 else:
454 else:
450 mode = 'tb'
455 mode = 'tb'
451
456
452 code = line
457 code = line
453 insertion = None
458 insertion = None
454
459
455 return mode, code, insertion
460 return mode, code, insertion
456
461
457 def get_tokens_unprocessed(self, text):
462 def get_tokens_unprocessed(self, text):
458 self.reset()
463 self.reset()
459 for match in line_re.finditer(text):
464 for match in line_re.finditer(text):
460 line = match.group()
465 line = match.group()
461 mode, code, insertion = self.get_mci(line)
466 mode, code, insertion = self.get_mci(line)
462
467
463 if mode != self.mode:
468 if mode != self.mode:
464 # Yield buffered tokens before transitioning to new mode.
469 # Yield buffered tokens before transitioning to new mode.
465 for token in self.buffered_tokens():
470 for token in self.buffered_tokens():
466 yield token
471 yield token
467 self.mode = mode
472 self.mode = mode
468
473
469 if insertion:
474 if insertion:
470 self.insertions.append((len(self.buffer), [insertion]))
475 self.insertions.append((len(self.buffer), [insertion]))
471 self.buffer += code
476 self.buffer += code
472
477
473 for token in self.buffered_tokens():
478 for token in self.buffered_tokens():
474 yield token
479 yield token
475
480
476 class IPyLexer(Lexer):
481 class IPyLexer(Lexer):
477 """
482 """
478 Primary lexer for all IPython-like code.
483 Primary lexer for all IPython-like code.
479
484
480 This is a simple helper lexer. If the first line of the text begins with
485 This is a simple helper lexer. If the first line of the text begins with
481 "In \[[0-9]+\]:", then the entire text is parsed with an IPython console
486 "In \[[0-9]+\]:", then the entire text is parsed with an IPython console
482 lexer. If not, then the entire text is parsed with an IPython lexer.
487 lexer. If not, then the entire text is parsed with an IPython lexer.
483
488
484 The goal is to reduce the number of lexers that are registered
489 The goal is to reduce the number of lexers that are registered
485 with Pygments.
490 with Pygments.
486
491
487 """
492 """
488 name = 'IPy session'
493 name = 'IPy session'
489 aliases = ['ipy']
494 aliases = ['ipy']
490
495
491 def __init__(self, **options):
496 def __init__(self, **options):
492 self.python3 = get_bool_opt(options, 'python3', False)
497 self.python3 = get_bool_opt(options, 'python3', False)
493 if self.python3:
498 if self.python3:
494 self.aliases = ['ipy3']
499 self.aliases = ['ipy3']
495 else:
500 else:
496 self.aliases = ['ipy2', 'ipy']
501 self.aliases = ['ipy2', 'ipy']
497
502
498 Lexer.__init__(self, **options)
503 Lexer.__init__(self, **options)
499
504
500 self.IPythonLexer = IPythonLexer(**options)
505 self.IPythonLexer = IPythonLexer(**options)
501 self.IPythonConsoleLexer = IPythonConsoleLexer(**options)
506 self.IPythonConsoleLexer = IPythonConsoleLexer(**options)
502
507
503 def get_tokens_unprocessed(self, text):
508 def get_tokens_unprocessed(self, text):
504 # Search for the input prompt anywhere...this allows code blocks to
509 # Search for the input prompt anywhere...this allows code blocks to
505 # begin with comments as well.
510 # begin with comments as well.
506 if re.match(r'.*(In \[[0-9]+\]:)', text.strip(), re.DOTALL):
511 if re.match(r'.*(In \[[0-9]+\]:)', text.strip(), re.DOTALL):
507 lex = self.IPythonConsoleLexer
512 lex = self.IPythonConsoleLexer
508 else:
513 else:
509 lex = self.IPythonLexer
514 lex = self.IPythonLexer
510 for token in lex.get_tokens_unprocessed(text):
515 for token in lex.get_tokens_unprocessed(text):
511 yield token
516 yield token
512
517
General Comments 0
You need to be logged in to leave comments. Login now