##// END OF EJS Templates
Fix mistake in previous commit
Thomas Kluyver -
Show More
@@ -1,841 +1,841 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 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16
16
17 __all__ = ['Inspector','InspectColors']
17 __all__ = ['Inspector','InspectColors']
18
18
19 # stdlib modules
19 # stdlib modules
20 import __builtin__
20 import __builtin__
21 import inspect
21 import inspect
22 import linecache
22 import linecache
23 import os
23 import os
24 import sys
24 import sys
25 import types
25 import types
26 from collections import namedtuple
26 from collections import namedtuple
27 try:
27 try:
28 from itertools import izip_longest
28 from itertools import izip_longest
29 except ImportError:
29 except ImportError:
30 from itertools import zip_longest as izip_longest
30 from itertools import zip_longest as izip_longest
31
31
32 # IPython's own
32 # IPython's own
33 from IPython.core import page
33 from IPython.core import page
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 io
36 from IPython.utils import io
37 from IPython.utils import py3compat
37 from IPython.utils import py3compat
38 from IPython.utils.text import indent
38 from IPython.utils.text import indent
39 from IPython.utils.wildcard import list_namespace
39 from IPython.utils.wildcard import list_namespace
40 from IPython.utils.coloransi import *
40 from IPython.utils.coloransi import *
41
41
42 #****************************************************************************
42 #****************************************************************************
43 # Builtin color schemes
43 # Builtin color schemes
44
44
45 Colors = TermColors # just a shorthand
45 Colors = TermColors # just a shorthand
46
46
47 # Build a few color schemes
47 # Build a few color schemes
48 NoColor = ColorScheme(
48 NoColor = ColorScheme(
49 'NoColor',{
49 'NoColor',{
50 'header' : Colors.NoColor,
50 'header' : Colors.NoColor,
51 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
51 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
52 } )
52 } )
53
53
54 LinuxColors = ColorScheme(
54 LinuxColors = ColorScheme(
55 'Linux',{
55 'Linux',{
56 'header' : Colors.LightRed,
56 'header' : Colors.LightRed,
57 'normal' : Colors.Normal # color off (usu. Colors.Normal)
57 'normal' : Colors.Normal # color off (usu. Colors.Normal)
58 } )
58 } )
59
59
60 LightBGColors = ColorScheme(
60 LightBGColors = ColorScheme(
61 'LightBG',{
61 'LightBG',{
62 'header' : Colors.Red,
62 'header' : Colors.Red,
63 'normal' : Colors.Normal # color off (usu. Colors.Normal)
63 'normal' : Colors.Normal # color off (usu. Colors.Normal)
64 } )
64 } )
65
65
66 # Build table of color schemes (needed by the parser)
66 # Build table of color schemes (needed by the parser)
67 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
67 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
68 'Linux')
68 'Linux')
69
69
70 #****************************************************************************
70 #****************************************************************************
71 # Auxiliary functions and objects
71 # Auxiliary functions and objects
72
72
73 # See the messaging spec for the definition of all these fields. This list
73 # See the messaging spec for the definition of all these fields. This list
74 # effectively defines the order of display
74 # effectively defines the order of display
75 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
75 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
76 'length', 'file', 'definition', 'docstring', 'source',
76 'length', 'file', 'definition', 'docstring', 'source',
77 'init_definition', 'class_docstring', 'init_docstring',
77 'init_definition', 'class_docstring', 'init_docstring',
78 'call_def', 'call_docstring',
78 'call_def', 'call_docstring',
79 # These won't be printed but will be used to determine how to
79 # These won't be printed but will be used to determine how to
80 # format the object
80 # format the object
81 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
81 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
82 ]
82 ]
83
83
84
84
85 def object_info(**kw):
85 def object_info(**kw):
86 """Make an object info dict with all fields present."""
86 """Make an object info dict with all fields present."""
87 infodict = dict(izip_longest(info_fields, [None]))
87 infodict = dict(izip_longest(info_fields, [None]))
88 infodict.update(kw)
88 infodict.update(kw)
89 return infodict
89 return infodict
90
90
91
91
92 def getdoc(obj):
92 def getdoc(obj):
93 """Stable wrapper around inspect.getdoc.
93 """Stable wrapper around inspect.getdoc.
94
94
95 This can't crash because of attribute problems.
95 This can't crash because of attribute problems.
96
96
97 It also attempts to call a getdoc() method on the given object. This
97 It also attempts to call a getdoc() method on the given object. This
98 allows objects which provide their docstrings via non-standard mechanisms
98 allows objects which provide their docstrings via non-standard mechanisms
99 (like Pyro proxies) to still be inspected by ipython's ? system."""
99 (like Pyro proxies) to still be inspected by ipython's ? system."""
100 # Allow objects to offer customized documentation via a getdoc method:
100 # Allow objects to offer customized documentation via a getdoc method:
101 try:
101 try:
102 ds = obj.getdoc()
102 ds = obj.getdoc()
103 except Exception:
103 except Exception:
104 pass
104 pass
105 else:
105 else:
106 # if we get extra info, we add it to the normal docstring.
106 # if we get extra info, we add it to the normal docstring.
107 if isinstance(ds, basestring):
107 if isinstance(ds, basestring):
108 return inspect.cleandoc(ds)
108 return inspect.cleandoc(ds)
109
109
110 try:
110 try:
111 return inspect.getdoc(obj)
111 return inspect.getdoc(obj)
112 except Exception:
112 except Exception:
113 # Harden against an inspect failure, which can occur with
113 # Harden against an inspect failure, which can occur with
114 # SWIG-wrapped extensions.
114 # SWIG-wrapped extensions.
115 return None
115 return None
116
116
117
117
118 def getsource(obj,is_binary=False):
118 def getsource(obj,is_binary=False):
119 """Wrapper around inspect.getsource.
119 """Wrapper around inspect.getsource.
120
120
121 This can be modified by other projects to provide customized source
121 This can be modified by other projects to provide customized source
122 extraction.
122 extraction.
123
123
124 Inputs:
124 Inputs:
125
125
126 - obj: an object whose source code we will attempt to extract.
126 - obj: an object whose source code we will attempt to extract.
127
127
128 Optional inputs:
128 Optional inputs:
129
129
130 - is_binary: whether the object is known to come from a binary source.
130 - is_binary: whether the object is known to come from a binary source.
131 This implementation will skip returning any output for binary objects, but
131 This implementation will skip returning any output for binary objects, but
132 custom extractors may know how to meaningfully process them."""
132 custom extractors may know how to meaningfully process them."""
133
133
134 if is_binary:
134 if is_binary:
135 return None
135 return None
136 else:
136 else:
137 # get source if obj was decorated with @decorator
137 # get source if obj was decorated with @decorator
138 if hasattr(obj,"__wrapped__"):
138 if hasattr(obj,"__wrapped__"):
139 obj = obj.__wrapped__
139 obj = obj.__wrapped__
140 try:
140 try:
141 src = inspect.getsource(obj)
141 src = inspect.getsource(obj)
142 except TypeError:
142 except TypeError:
143 if hasattr(obj,'__class__'):
143 if hasattr(obj,'__class__'):
144 src = inspect.getsource(obj.__class__)
144 src = inspect.getsource(obj.__class__)
145 return src
145 return src
146
146
147 def getargspec(obj):
147 def getargspec(obj):
148 """Get the names and default values of a function's arguments.
148 """Get the names and default values of a function's arguments.
149
149
150 A tuple of four things is returned: (args, varargs, varkw, defaults).
150 A tuple of four things is returned: (args, varargs, varkw, defaults).
151 'args' is a list of the argument names (it may contain nested lists).
151 'args' is a list of the argument names (it may contain nested lists).
152 'varargs' and 'varkw' are the names of the * and ** arguments or None.
152 'varargs' and 'varkw' are the names of the * and ** arguments or None.
153 'defaults' is an n-tuple of the default values of the last n arguments.
153 'defaults' is an n-tuple of the default values of the last n arguments.
154
154
155 Modified version of inspect.getargspec from the Python Standard
155 Modified version of inspect.getargspec from the Python Standard
156 Library."""
156 Library."""
157
157
158 if inspect.isfunction(obj):
158 if inspect.isfunction(obj):
159 func_obj = obj
159 func_obj = obj
160 elif inspect.ismethod(obj):
160 elif inspect.ismethod(obj):
161 func_obj = obj.im_func
161 func_obj = obj.im_func
162 elif hasattr(obj, '__call__'):
162 elif hasattr(obj, '__call__'):
163 func_obj = obj.__call__
163 func_obj = obj.__call__
164 else:
164 else:
165 raise TypeError('arg is not a Python function')
165 raise TypeError('arg is not a Python function')
166 args, varargs, varkw = inspect.getargs(func_obj.func_code)
166 args, varargs, varkw = inspect.getargs(func_obj.func_code)
167 return args, varargs, varkw, func_obj.func_defaults
167 return args, varargs, varkw, func_obj.func_defaults
168
168
169
169
170 def format_argspec(argspec):
170 def format_argspec(argspec):
171 """Format argspect, convenience wrapper around inspect's.
171 """Format argspect, convenience wrapper around inspect's.
172
172
173 This takes a dict instead of ordered arguments and calls
173 This takes a dict instead of ordered arguments and calls
174 inspect.format_argspec with the arguments in the necessary order.
174 inspect.format_argspec with the arguments in the necessary order.
175 """
175 """
176 return inspect.formatargspec(argspec['args'], argspec['varargs'],
176 return inspect.formatargspec(argspec['args'], argspec['varargs'],
177 argspec['varkw'], argspec['defaults'])
177 argspec['varkw'], argspec['defaults'])
178
178
179
179
180 def call_tip(oinfo, format_call=True):
180 def call_tip(oinfo, format_call=True):
181 """Extract call tip data from an oinfo dict.
181 """Extract call tip data from an oinfo dict.
182
182
183 Parameters
183 Parameters
184 ----------
184 ----------
185 oinfo : dict
185 oinfo : dict
186
186
187 format_call : bool, optional
187 format_call : bool, optional
188 If True, the call line is formatted and returned as a string. If not, a
188 If True, the call line is formatted and returned as a string. If not, a
189 tuple of (name, argspec) is returned.
189 tuple of (name, argspec) is returned.
190
190
191 Returns
191 Returns
192 -------
192 -------
193 call_info : None, str or (str, dict) tuple.
193 call_info : None, str or (str, dict) tuple.
194 When format_call is True, the whole call information is formattted as a
194 When format_call is True, the whole call information is formattted as a
195 single string. Otherwise, the object's name and its argspec dict are
195 single string. Otherwise, the object's name and its argspec dict are
196 returned. If no call information is available, None is returned.
196 returned. If no call information is available, None is returned.
197
197
198 docstring : str or None
198 docstring : str or None
199 The most relevant docstring for calling purposes is returned, if
199 The most relevant docstring for calling purposes is returned, if
200 available. The priority is: call docstring for callable instances, then
200 available. The priority is: call docstring for callable instances, then
201 constructor docstring for classes, then main object's docstring otherwise
201 constructor docstring for classes, then main object's docstring otherwise
202 (regular functions).
202 (regular functions).
203 """
203 """
204 # Get call definition
204 # Get call definition
205 argspec = oinfo.get('argspec')
205 argspec = oinfo.get('argspec')
206 if argspec is None:
206 if argspec is None:
207 call_line = None
207 call_line = None
208 else:
208 else:
209 # Callable objects will have 'self' as their first argument, prune
209 # Callable objects will have 'self' as their first argument, prune
210 # it out if it's there for clarity (since users do *not* pass an
210 # it out if it's there for clarity (since users do *not* pass an
211 # extra first argument explicitly).
211 # extra first argument explicitly).
212 try:
212 try:
213 has_self = argspec['args'][0] == 'self'
213 has_self = argspec['args'][0] == 'self'
214 except (KeyError, IndexError):
214 except (KeyError, IndexError):
215 pass
215 pass
216 else:
216 else:
217 if has_self:
217 if has_self:
218 argspec['args'] = argspec['args'][1:]
218 argspec['args'] = argspec['args'][1:]
219
219
220 call_line = oinfo['name']+format_argspec(argspec)
220 call_line = oinfo['name']+format_argspec(argspec)
221
221
222 # Now get docstring.
222 # Now get docstring.
223 # The priority is: call docstring, constructor docstring, main one.
223 # The priority is: call docstring, constructor docstring, main one.
224 doc = oinfo.get('call_docstring')
224 doc = oinfo.get('call_docstring')
225 if doc is None:
225 if doc is None:
226 doc = oinfo.get('init_docstring')
226 doc = oinfo.get('init_docstring')
227 if doc is None:
227 if doc is None:
228 doc = oinfo.get('docstring','')
228 doc = oinfo.get('docstring','')
229
229
230 return call_line, doc
230 return call_line, doc
231
231
232
232
233 def find_file(obj):
233 def find_file(obj):
234 """Find the absolute path to the file where an object was defined.
234 """Find the absolute path to the file where an object was defined.
235
235
236 This is essentially a robust wrapper around `inspect.getabsfile`.
236 This is essentially a robust wrapper around `inspect.getabsfile`.
237
237
238 Returns None if no file can be found.
238 Returns None if no file can be found.
239
239
240 Parameters
240 Parameters
241 ----------
241 ----------
242 obj : any Python object
242 obj : any Python object
243
243
244 Returns
244 Returns
245 -------
245 -------
246 fname : str
246 fname : str
247 The absolute path to the file where the object was defined.
247 The absolute path to the file where the object was defined.
248 """
248 """
249 # get source if obj was decorated with @decorator
249 # get source if obj was decorated with @decorator
250 if hasattr(obj, '__wrapped__'):
250 if hasattr(obj, '__wrapped__'):
251 obj = obj.__wrapped__
251 obj = obj.__wrapped__
252
252
253 fname = None
253 fname = None
254 try:
254 try:
255 fname = inspect.getabsfile(obj)
255 fname = inspect.getabsfile(obj)
256 except TypeError:
256 except TypeError:
257 # For an instance, the file that matters is where its class was
257 # For an instance, the file that matters is where its class was
258 # declared.
258 # declared.
259 if hasattr(obj, '__class__'):
259 if hasattr(obj, '__class__'):
260 try:
260 try:
261 fname = inspect.getabsfile(obj.__class__)
261 fname = inspect.getabsfile(obj.__class__)
262 except TypeError:
262 except TypeError:
263 # Can happen for builtins
263 # Can happen for builtins
264 pass
264 pass
265 except:
265 except:
266 pass
266 pass
267 return fname
267 return fname
268
268
269
269
270 def find_source_lines(obj):
270 def find_source_lines(obj):
271 """Find the line number in a file where an object was defined.
271 """Find the line number in a file where an object was defined.
272
272
273 This is essentially a robust wrapper around `inspect.getsourcelines`.
273 This is essentially a robust wrapper around `inspect.getsourcelines`.
274
274
275 Returns None if no file can be found.
275 Returns None if no file can be found.
276
276
277 Parameters
277 Parameters
278 ----------
278 ----------
279 obj : any Python object
279 obj : any Python object
280
280
281 Returns
281 Returns
282 -------
282 -------
283 lineno : int
283 lineno : int
284 The line number where the object definition starts.
284 The line number where the object definition starts.
285 """
285 """
286 # get source if obj was decorated with @decorator
286 # get source if obj was decorated with @decorator
287 if hasattr(obj, '__wrapped__'):
287 if hasattr(obj, '__wrapped__'):
288 obj = obj.__wrapped__
288 obj = obj.__wrapped__
289
289
290 try:
290 try:
291 try:
291 try:
292 lineno = inspect.getsourcelines(obj)[1]
292 lineno = inspect.getsourcelines(obj)[1]
293 except TypeError:
293 except TypeError:
294 # For instances, try the class object like getsource() does
294 # For instances, try the class object like getsource() does
295 if hasattr(obj, '__class__'):
295 if hasattr(obj, '__class__'):
296 lineno = inspect.getsourcelines(obj.__class__)[1]
296 lineno = inspect.getsourcelines(obj.__class__)[1]
297 except:
297 except:
298 return None
298 return None
299
299
300 return lineno
300 return lineno
301
301
302
302
303 class Inspector:
303 class Inspector:
304 def __init__(self, color_table=InspectColors,
304 def __init__(self, color_table=InspectColors,
305 code_color_table=PyColorize.ANSICodeColors,
305 code_color_table=PyColorize.ANSICodeColors,
306 scheme='NoColor',
306 scheme='NoColor',
307 str_detail_level=0):
307 str_detail_level=0):
308 self.color_table = color_table
308 self.color_table = color_table
309 self.parser = PyColorize.Parser(code_color_table,out='str')
309 self.parser = PyColorize.Parser(code_color_table,out='str')
310 self.format = self.parser.format
310 self.format = self.parser.format
311 self.str_detail_level = str_detail_level
311 self.str_detail_level = str_detail_level
312 self.set_active_scheme(scheme)
312 self.set_active_scheme(scheme)
313
313
314 def _getdef(self,obj,oname=''):
314 def _getdef(self,obj,oname=''):
315 """Return the definition header for any callable object.
315 """Return the definition header for any callable object.
316
316
317 If any exception is generated, None is returned instead and the
317 If any exception is generated, None is returned instead and the
318 exception is suppressed."""
318 exception is suppressed."""
319
319
320 try:
320 try:
321 # We need a plain string here, NOT unicode!
321 # We need a plain string here, NOT unicode!
322 hdef = oname + inspect.formatargspec(*getargspec(obj))
322 hdef = oname + inspect.formatargspec(*getargspec(obj))
323 return py3compat.unicode_to_str(hdef, 'ascii')
323 return py3compat.unicode_to_str(hdef, 'ascii')
324 except:
324 except:
325 return None
325 return None
326
326
327 def __head(self,h):
327 def __head(self,h):
328 """Return a header string with proper colors."""
328 """Return a header string with proper colors."""
329 return '%s%s%s' % (self.color_table.active_colors.header,h,
329 return '%s%s%s' % (self.color_table.active_colors.header,h,
330 self.color_table.active_colors.normal)
330 self.color_table.active_colors.normal)
331
331
332 def set_active_scheme(self, scheme):
332 def set_active_scheme(self, scheme):
333 self.color_table.set_active_scheme(scheme)
333 self.color_table.set_active_scheme(scheme)
334 self.parser.color_table.set_active_scheme(scheme)
334 self.parser.color_table.set_active_scheme(scheme)
335
335
336 def noinfo(self, msg, oname):
336 def noinfo(self, msg, oname):
337 """Generic message when no information is found."""
337 """Generic message when no information is found."""
338 print 'No %s found' % msg,
338 print 'No %s found' % msg,
339 if oname:
339 if oname:
340 print 'for %s' % oname
340 print 'for %s' % oname
341 else:
341 else:
342 print
342 print
343
343
344 def pdef(self, obj, oname=''):
344 def pdef(self, obj, oname=''):
345 """Print the definition header for any callable object.
345 """Print the definition header for any callable object.
346
346
347 If the object is a class, print the constructor information."""
347 If the object is a class, print the constructor information."""
348
348
349 if not callable(obj):
349 if not callable(obj):
350 print 'Object is not callable.'
350 print 'Object is not callable.'
351 return
351 return
352
352
353 header = ''
353 header = ''
354
354
355 if inspect.isclass(obj):
355 if inspect.isclass(obj):
356 header = self.__head('Class constructor information:\n')
356 header = self.__head('Class constructor information:\n')
357 obj = obj.__init__
357 obj = obj.__init__
358 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
358 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
359 obj = obj.__call__
359 obj = obj.__call__
360
360
361 output = self._getdef(obj,oname)
361 output = self._getdef(obj,oname)
362 if output is None:
362 if output is None:
363 self.noinfo('definition header',oname)
363 self.noinfo('definition header',oname)
364 else:
364 else:
365 print >>io.stdout, header,self.format(output),
365 print >>io.stdout, header,self.format(output),
366
366
367 # In Python 3, all classes are new-style, so they all have __init__.
367 # In Python 3, all classes are new-style, so they all have __init__.
368 @skip_doctest_py3
368 @skip_doctest_py3
369 def pdoc(self,obj,oname='',formatter = None):
369 def pdoc(self,obj,oname='',formatter = None):
370 """Print the docstring for any object.
370 """Print the docstring for any object.
371
371
372 Optional:
372 Optional:
373 -formatter: a function to run the docstring through for specially
373 -formatter: a function to run the docstring through for specially
374 formatted docstrings.
374 formatted docstrings.
375
375
376 Examples
376 Examples
377 --------
377 --------
378
378
379 In [1]: class NoInit:
379 In [1]: class NoInit:
380 ...: pass
380 ...: pass
381
381
382 In [2]: class NoDoc:
382 In [2]: class NoDoc:
383 ...: def __init__(self):
383 ...: def __init__(self):
384 ...: pass
384 ...: pass
385
385
386 In [3]: %pdoc NoDoc
386 In [3]: %pdoc NoDoc
387 No documentation found for NoDoc
387 No documentation found for NoDoc
388
388
389 In [4]: %pdoc NoInit
389 In [4]: %pdoc NoInit
390 No documentation found for NoInit
390 No documentation found for NoInit
391
391
392 In [5]: obj = NoInit()
392 In [5]: obj = NoInit()
393
393
394 In [6]: %pdoc obj
394 In [6]: %pdoc obj
395 No documentation found for obj
395 No documentation found for obj
396
396
397 In [5]: obj2 = NoDoc()
397 In [5]: obj2 = NoDoc()
398
398
399 In [6]: %pdoc obj2
399 In [6]: %pdoc obj2
400 No documentation found for obj2
400 No documentation found for obj2
401 """
401 """
402
402
403 head = self.__head # For convenience
403 head = self.__head # For convenience
404 lines = []
404 lines = []
405 ds = getdoc(obj)
405 ds = getdoc(obj)
406 if formatter:
406 if formatter:
407 ds = formatter(ds)
407 ds = formatter(ds)
408 if ds:
408 if ds:
409 lines.append(head("Class Docstring:"))
409 lines.append(head("Class Docstring:"))
410 lines.append(indent(ds))
410 lines.append(indent(ds))
411 if inspect.isclass(obj) and hasattr(obj, '__init__'):
411 if inspect.isclass(obj) and hasattr(obj, '__init__'):
412 init_ds = getdoc(obj.__init__)
412 init_ds = getdoc(obj.__init__)
413 if init_ds is not None:
413 if init_ds is not None:
414 lines.append(head("Constructor Docstring:"))
414 lines.append(head("Constructor Docstring:"))
415 lines.append(indent(init_ds))
415 lines.append(indent(init_ds))
416 elif hasattr(obj,'__call__'):
416 elif hasattr(obj,'__call__'):
417 call_ds = getdoc(obj.__call__)
417 call_ds = getdoc(obj.__call__)
418 if call_ds:
418 if call_ds:
419 lines.append(head("Calling Docstring:"))
419 lines.append(head("Calling Docstring:"))
420 lines.append(indent(call_ds))
420 lines.append(indent(call_ds))
421
421
422 if not lines:
422 if not lines:
423 self.noinfo('documentation',oname)
423 self.noinfo('documentation',oname)
424 else:
424 else:
425 page.page('\n'.join(lines))
425 page.page('\n'.join(lines))
426
426
427 def psource(self,obj,oname=''):
427 def psource(self,obj,oname=''):
428 """Print the source code for an object."""
428 """Print the source code for an object."""
429
429
430 # Flush the source cache because inspect can return out-of-date source
430 # Flush the source cache because inspect can return out-of-date source
431 linecache.checkcache()
431 linecache.checkcache()
432 try:
432 try:
433 src = getsource(obj)
433 src = getsource(obj)
434 except:
434 except:
435 self.noinfo('source',oname)
435 self.noinfo('source',oname)
436 else:
436 else:
437 page.page(self.format(py3compat.unicode_to_str(src)))
437 page.page(self.format(py3compat.unicode_to_str(src)))
438
438
439 def pfile(self, obj, oname=''):
439 def pfile(self, obj, oname=''):
440 """Show the whole file where an object was defined."""
440 """Show the whole file where an object was defined."""
441
441
442 lineno = find_source_lines(obj)
442 lineno = find_source_lines(obj)
443 if lineno is None:
443 if lineno is None:
444 self.noinfo('file', oname)
444 self.noinfo('file', oname)
445 return
445 return
446
446
447 ofile = find_file(obj)
447 ofile = find_file(obj)
448 # run contents of file through pager starting at line where the object
448 # run contents of file through pager starting at line where the object
449 # is defined, as long as the file isn't binary and is actually on the
449 # is defined, as long as the file isn't binary and is actually on the
450 # filesystem.
450 # filesystem.
451 if ofile.endswith(('.so', '.dll', '.pyd')):
451 if ofile.endswith(('.so', '.dll', '.pyd')):
452 print 'File %r is binary, not printing.' % ofile
452 print 'File %r is binary, not printing.' % ofile
453 elif not os.path.isfile(ofile):
453 elif not os.path.isfile(ofile):
454 print 'File %r does not exist, not printing.' % ofile
454 print 'File %r does not exist, not printing.' % ofile
455 else:
455 else:
456 # Print only text files, not extension binaries. Note that
456 # Print only text files, not extension binaries. Note that
457 # getsourcelines returns lineno with 1-offset and page() uses
457 # getsourcelines returns lineno with 1-offset and page() uses
458 # 0-offset, so we must adjust.
458 # 0-offset, so we must adjust.
459 page.page(self.format(open(ofile).read()), lineno-1)
459 page.page(self.format(open(ofile).read()), lineno-1)
460
460
461 def _format_fields(self, fields, title_width=12):
461 def _format_fields(self, fields, title_width=12):
462 """Formats a list of fields for display.
462 """Formats a list of fields for display.
463
463
464 Parameters
464 Parameters
465 ----------
465 ----------
466 fields : list
466 fields : list
467 A list of 2-tuples: (field_title, field_content)
467 A list of 2-tuples: (field_title, field_content)
468 title_width : int
468 title_width : int
469 How many characters to pad titles to. Default 12.
469 How many characters to pad titles to. Default 12.
470 """
470 """
471 out = []
471 out = []
472 header = self.__head
472 header = self.__head
473 for title, content in fields:
473 for title, content in fields:
474 if len(content.splitlines()) > 1:
474 if len(content.splitlines()) > 1:
475 title = header(title + ":") + "\n"
475 title = header(title + ":") + "\n"
476 else:
476 else:
477 title = header((title+":").ljust(title_width))
477 title = header((title+":").ljust(title_width))
478 out.append(title + content)
478 out.append(title + content)
479 return "\n".join(out)
479 return "\n".join(out)
480
480
481 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
481 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
482 pinfo_fields1 = [("Type", "type_name"),
482 pinfo_fields1 = [("Type", "type_name"),
483 ]
483 ]
484
484
485 pinfo_fields2 = [("String Form", "string_form"),
485 pinfo_fields2 = [("String Form", "string_form"),
486 ]
486 ]
487
487
488 pinfo_fields3 = [("Length", "length"),
488 pinfo_fields3 = [("Length", "length"),
489 ("File", "file"),
489 ("File", "file"),
490 ("Definition", "definition"),
490 ("Definition", "definition"),
491 ]
491 ]
492
492
493 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
493 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
494 ("Constructor Docstring","init_docstring"),
494 ("Constructor Docstring","init_docstring"),
495 ("Call def", "call_def"),
495 ("Call def", "call_def"),
496 ("Call docstring", "call_docstring")]
496 ("Call docstring", "call_docstring")]
497
497
498 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
498 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
499 """Show detailed information about an object.
499 """Show detailed information about an object.
500
500
501 Optional arguments:
501 Optional arguments:
502
502
503 - oname: name of the variable pointing to the object.
503 - oname: name of the variable pointing to the object.
504
504
505 - formatter: special formatter for docstrings (see pdoc)
505 - formatter: special formatter for docstrings (see pdoc)
506
506
507 - info: a structure with some information fields which may have been
507 - info: a structure with some information fields which may have been
508 precomputed already.
508 precomputed already.
509
509
510 - detail_level: if set to 1, more information is given.
510 - detail_level: if set to 1, more information is given.
511 """
511 """
512 info = self.info(obj, oname=oname, formatter=formatter,
512 info = self.info(obj, oname=oname, formatter=formatter,
513 info=info, detail_level=detail_level)
513 info=info, detail_level=detail_level)
514 displayfields = []
514 displayfields = []
515 def add_fields(fields):
515 def add_fields(fields):
516 for title, key in fields:
516 for title, key in fields:
517 field = info[key]
517 field = info[key]
518 if field is not None:
518 if field is not None:
519 displayfields.append((title, field.rstrip()))
519 displayfields.append((title, field.rstrip()))
520
520
521 add_fields(self.pinfo_fields1)
521 add_fields(self.pinfo_fields1)
522
522
523 # Base class for old-style instances
523 # Base class for old-style instances
524 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
524 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
525 displayfield.append(("Base Class", info['base_class'].rstrip()))
525 displayfields.append(("Base Class", info['base_class'].rstrip()))
526
526
527 add_fields(self.pinfo_fields2)
527 add_fields(self.pinfo_fields2)
528
528
529 # Namespace
529 # Namespace
530 if info['namespace'] != 'Interactive':
530 if info['namespace'] != 'Interactive':
531 displayfield.append(("Namespace", info['namespace'].rstrip()))
531 displayfields.append(("Namespace", info['namespace'].rstrip()))
532
532
533 add_fields(self.pinfo_fields3)
533 add_fields(self.pinfo_fields3)
534
534
535 # Source or docstring, depending on detail level and whether
535 # Source or docstring, depending on detail level and whether
536 # source found.
536 # source found.
537 if detail_level > 0 and info['source'] is not None:
537 if detail_level > 0 and info['source'] is not None:
538 displayfields.append(("Source", self.format(py3compat.cast_bytes_py2(info['source']))))
538 displayfields.append(("Source", self.format(py3compat.cast_bytes_py2(info['source']))))
539 elif info['docstring'] is not None:
539 elif info['docstring'] is not None:
540 displayfields.append(("Docstring", info["docstring"]))
540 displayfields.append(("Docstring", info["docstring"]))
541
541
542 # Constructor info for classes
542 # Constructor info for classes
543 if info['isclass']:
543 if info['isclass']:
544 if info['init_definition'] or info['init_docstring']:
544 if info['init_definition'] or info['init_docstring']:
545 displayfields.append(("Constructor information", ""))
545 displayfields.append(("Constructor information", ""))
546 if info['init_definition'] is not None:
546 if info['init_definition'] is not None:
547 displayfields.append((" Definition",
547 displayfields.append((" Definition",
548 info['init_definition'].rstrip()))
548 info['init_definition'].rstrip()))
549 if info['init_docstring'] is not None:
549 if info['init_docstring'] is not None:
550 displayfields.append((" Docstring",
550 displayfields.append((" Docstring",
551 indent(info['init_docstring'])))
551 indent(info['init_docstring'])))
552
552
553 # Info for objects:
553 # Info for objects:
554 else:
554 else:
555 add_fields(self.pinfo_fields_obj)
555 add_fields(self.pinfo_fields_obj)
556
556
557 # Finally send to printer/pager:
557 # Finally send to printer/pager:
558 if displayfields:
558 if displayfields:
559 page.page(self._format_fields(displayfields))
559 page.page(self._format_fields(displayfields))
560
560
561 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
561 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
562 """Compute a dict with detailed information about an object.
562 """Compute a dict with detailed information about an object.
563
563
564 Optional arguments:
564 Optional arguments:
565
565
566 - oname: name of the variable pointing to the object.
566 - oname: name of the variable pointing to the object.
567
567
568 - formatter: special formatter for docstrings (see pdoc)
568 - formatter: special formatter for docstrings (see pdoc)
569
569
570 - info: a structure with some information fields which may have been
570 - info: a structure with some information fields which may have been
571 precomputed already.
571 precomputed already.
572
572
573 - detail_level: if set to 1, more information is given.
573 - detail_level: if set to 1, more information is given.
574 """
574 """
575
575
576 obj_type = type(obj)
576 obj_type = type(obj)
577
577
578 header = self.__head
578 header = self.__head
579 if info is None:
579 if info is None:
580 ismagic = 0
580 ismagic = 0
581 isalias = 0
581 isalias = 0
582 ospace = ''
582 ospace = ''
583 else:
583 else:
584 ismagic = info.ismagic
584 ismagic = info.ismagic
585 isalias = info.isalias
585 isalias = info.isalias
586 ospace = info.namespace
586 ospace = info.namespace
587
587
588 # Get docstring, special-casing aliases:
588 # Get docstring, special-casing aliases:
589 if isalias:
589 if isalias:
590 if not callable(obj):
590 if not callable(obj):
591 try:
591 try:
592 ds = "Alias to the system command:\n %s" % obj[1]
592 ds = "Alias to the system command:\n %s" % obj[1]
593 except:
593 except:
594 ds = "Alias: " + str(obj)
594 ds = "Alias: " + str(obj)
595 else:
595 else:
596 ds = "Alias to " + str(obj)
596 ds = "Alias to " + str(obj)
597 if obj.__doc__:
597 if obj.__doc__:
598 ds += "\nDocstring:\n" + obj.__doc__
598 ds += "\nDocstring:\n" + obj.__doc__
599 else:
599 else:
600 ds = getdoc(obj)
600 ds = getdoc(obj)
601 if ds is None:
601 if ds is None:
602 ds = '<no docstring>'
602 ds = '<no docstring>'
603 if formatter is not None:
603 if formatter is not None:
604 ds = formatter(ds)
604 ds = formatter(ds)
605
605
606 # store output in a dict, we initialize it here and fill it as we go
606 # store output in a dict, we initialize it here and fill it as we go
607 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
607 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
608
608
609 string_max = 200 # max size of strings to show (snipped if longer)
609 string_max = 200 # max size of strings to show (snipped if longer)
610 shalf = int((string_max -5)/2)
610 shalf = int((string_max -5)/2)
611
611
612 if ismagic:
612 if ismagic:
613 obj_type_name = 'Magic function'
613 obj_type_name = 'Magic function'
614 elif isalias:
614 elif isalias:
615 obj_type_name = 'System alias'
615 obj_type_name = 'System alias'
616 else:
616 else:
617 obj_type_name = obj_type.__name__
617 obj_type_name = obj_type.__name__
618 out['type_name'] = obj_type_name
618 out['type_name'] = obj_type_name
619
619
620 try:
620 try:
621 bclass = obj.__class__
621 bclass = obj.__class__
622 out['base_class'] = str(bclass)
622 out['base_class'] = str(bclass)
623 except: pass
623 except: pass
624
624
625 # String form, but snip if too long in ? form (full in ??)
625 # String form, but snip if too long in ? form (full in ??)
626 if detail_level >= self.str_detail_level:
626 if detail_level >= self.str_detail_level:
627 try:
627 try:
628 ostr = str(obj)
628 ostr = str(obj)
629 str_head = 'string_form'
629 str_head = 'string_form'
630 if not detail_level and len(ostr)>string_max:
630 if not detail_level and len(ostr)>string_max:
631 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
631 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
632 ostr = ("\n" + " " * len(str_head.expandtabs())).\
632 ostr = ("\n" + " " * len(str_head.expandtabs())).\
633 join(q.strip() for q in ostr.split("\n"))
633 join(q.strip() for q in ostr.split("\n"))
634 out[str_head] = ostr
634 out[str_head] = ostr
635 except:
635 except:
636 pass
636 pass
637
637
638 if ospace:
638 if ospace:
639 out['namespace'] = ospace
639 out['namespace'] = ospace
640
640
641 # Length (for strings and lists)
641 # Length (for strings and lists)
642 try:
642 try:
643 out['length'] = str(len(obj))
643 out['length'] = str(len(obj))
644 except: pass
644 except: pass
645
645
646 # Filename where object was defined
646 # Filename where object was defined
647 binary_file = False
647 binary_file = False
648 fname = find_file(obj)
648 fname = find_file(obj)
649 if fname is None:
649 if fname is None:
650 # if anything goes wrong, we don't want to show source, so it's as
650 # if anything goes wrong, we don't want to show source, so it's as
651 # if the file was binary
651 # if the file was binary
652 binary_file = True
652 binary_file = True
653 else:
653 else:
654 if fname.endswith(('.so', '.dll', '.pyd')):
654 if fname.endswith(('.so', '.dll', '.pyd')):
655 binary_file = True
655 binary_file = True
656 elif fname.endswith('<string>'):
656 elif fname.endswith('<string>'):
657 fname = 'Dynamically generated function. No source code available.'
657 fname = 'Dynamically generated function. No source code available.'
658 out['file'] = fname
658 out['file'] = fname
659
659
660 # reconstruct the function definition and print it:
660 # reconstruct the function definition and print it:
661 defln = self._getdef(obj, oname)
661 defln = self._getdef(obj, oname)
662 if defln:
662 if defln:
663 out['definition'] = self.format(defln)
663 out['definition'] = self.format(defln)
664
664
665 # Docstrings only in detail 0 mode, since source contains them (we
665 # Docstrings only in detail 0 mode, since source contains them (we
666 # avoid repetitions). If source fails, we add them back, see below.
666 # avoid repetitions). If source fails, we add them back, see below.
667 if ds and detail_level == 0:
667 if ds and detail_level == 0:
668 out['docstring'] = ds
668 out['docstring'] = ds
669
669
670 # Original source code for any callable
670 # Original source code for any callable
671 if detail_level:
671 if detail_level:
672 # Flush the source cache because inspect can return out-of-date
672 # Flush the source cache because inspect can return out-of-date
673 # source
673 # source
674 linecache.checkcache()
674 linecache.checkcache()
675 source = None
675 source = None
676 try:
676 try:
677 try:
677 try:
678 source = getsource(obj, binary_file)
678 source = getsource(obj, binary_file)
679 except TypeError:
679 except TypeError:
680 if hasattr(obj, '__class__'):
680 if hasattr(obj, '__class__'):
681 source = getsource(obj.__class__, binary_file)
681 source = getsource(obj.__class__, binary_file)
682 if source is not None:
682 if source is not None:
683 out['source'] = source.rstrip()
683 out['source'] = source.rstrip()
684 except Exception:
684 except Exception:
685 pass
685 pass
686
686
687 if ds and source is None:
687 if ds and source is None:
688 out['docstring'] = ds
688 out['docstring'] = ds
689
689
690
690
691 # Constructor docstring for classes
691 # Constructor docstring for classes
692 if inspect.isclass(obj):
692 if inspect.isclass(obj):
693 out['isclass'] = True
693 out['isclass'] = True
694 # reconstruct the function definition and print it:
694 # reconstruct the function definition and print it:
695 try:
695 try:
696 obj_init = obj.__init__
696 obj_init = obj.__init__
697 except AttributeError:
697 except AttributeError:
698 init_def = init_ds = None
698 init_def = init_ds = None
699 else:
699 else:
700 init_def = self._getdef(obj_init,oname)
700 init_def = self._getdef(obj_init,oname)
701 init_ds = getdoc(obj_init)
701 init_ds = getdoc(obj_init)
702 # Skip Python's auto-generated docstrings
702 # Skip Python's auto-generated docstrings
703 if init_ds and \
703 if init_ds and \
704 init_ds.startswith('x.__init__(...) initializes'):
704 init_ds.startswith('x.__init__(...) initializes'):
705 init_ds = None
705 init_ds = None
706
706
707 if init_def or init_ds:
707 if init_def or init_ds:
708 if init_def:
708 if init_def:
709 out['init_definition'] = self.format(init_def)
709 out['init_definition'] = self.format(init_def)
710 if init_ds:
710 if init_ds:
711 out['init_docstring'] = init_ds
711 out['init_docstring'] = init_ds
712
712
713 # and class docstring for instances:
713 # and class docstring for instances:
714 else:
714 else:
715 # First, check whether the instance docstring is identical to the
715 # First, check whether the instance docstring is identical to the
716 # class one, and print it separately if they don't coincide. In
716 # class one, and print it separately if they don't coincide. In
717 # most cases they will, but it's nice to print all the info for
717 # most cases they will, but it's nice to print all the info for
718 # objects which use instance-customized docstrings.
718 # objects which use instance-customized docstrings.
719 if ds:
719 if ds:
720 try:
720 try:
721 cls = getattr(obj,'__class__')
721 cls = getattr(obj,'__class__')
722 except:
722 except:
723 class_ds = None
723 class_ds = None
724 else:
724 else:
725 class_ds = getdoc(cls)
725 class_ds = getdoc(cls)
726 # Skip Python's auto-generated docstrings
726 # Skip Python's auto-generated docstrings
727 if class_ds and \
727 if class_ds and \
728 (class_ds.startswith('function(code, globals[,') or \
728 (class_ds.startswith('function(code, globals[,') or \
729 class_ds.startswith('instancemethod(function, instance,') or \
729 class_ds.startswith('instancemethod(function, instance,') or \
730 class_ds.startswith('module(name[,') ):
730 class_ds.startswith('module(name[,') ):
731 class_ds = None
731 class_ds = None
732 if class_ds and ds != class_ds:
732 if class_ds and ds != class_ds:
733 out['class_docstring'] = class_ds
733 out['class_docstring'] = class_ds
734
734
735 # Next, try to show constructor docstrings
735 # Next, try to show constructor docstrings
736 try:
736 try:
737 init_ds = getdoc(obj.__init__)
737 init_ds = getdoc(obj.__init__)
738 # Skip Python's auto-generated docstrings
738 # Skip Python's auto-generated docstrings
739 if init_ds and \
739 if init_ds and \
740 init_ds.startswith('x.__init__(...) initializes'):
740 init_ds.startswith('x.__init__(...) initializes'):
741 init_ds = None
741 init_ds = None
742 except AttributeError:
742 except AttributeError:
743 init_ds = None
743 init_ds = None
744 if init_ds:
744 if init_ds:
745 out['init_docstring'] = init_ds
745 out['init_docstring'] = init_ds
746
746
747 # Call form docstring for callable instances
747 # Call form docstring for callable instances
748 if hasattr(obj, '__call__'):
748 if hasattr(obj, '__call__'):
749 call_def = self._getdef(obj.__call__, oname)
749 call_def = self._getdef(obj.__call__, oname)
750 if call_def is not None:
750 if call_def is not None:
751 out['call_def'] = self.format(call_def)
751 out['call_def'] = self.format(call_def)
752 call_ds = getdoc(obj.__call__)
752 call_ds = getdoc(obj.__call__)
753 # Skip Python's auto-generated docstrings
753 # Skip Python's auto-generated docstrings
754 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
754 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
755 call_ds = None
755 call_ds = None
756 if call_ds:
756 if call_ds:
757 out['call_docstring'] = call_ds
757 out['call_docstring'] = call_ds
758
758
759 # Compute the object's argspec as a callable. The key is to decide
759 # Compute the object's argspec as a callable. The key is to decide
760 # whether to pull it from the object itself, from its __init__ or
760 # whether to pull it from the object itself, from its __init__ or
761 # from its __call__ method.
761 # from its __call__ method.
762
762
763 if inspect.isclass(obj):
763 if inspect.isclass(obj):
764 # Old-style classes need not have an __init__
764 # Old-style classes need not have an __init__
765 callable_obj = getattr(obj, "__init__", None)
765 callable_obj = getattr(obj, "__init__", None)
766 elif callable(obj):
766 elif callable(obj):
767 callable_obj = obj
767 callable_obj = obj
768 else:
768 else:
769 callable_obj = None
769 callable_obj = None
770
770
771 if callable_obj:
771 if callable_obj:
772 try:
772 try:
773 args, varargs, varkw, defaults = getargspec(callable_obj)
773 args, varargs, varkw, defaults = getargspec(callable_obj)
774 except (TypeError, AttributeError):
774 except (TypeError, AttributeError):
775 # For extensions/builtins we can't retrieve the argspec
775 # For extensions/builtins we can't retrieve the argspec
776 pass
776 pass
777 else:
777 else:
778 out['argspec'] = dict(args=args, varargs=varargs,
778 out['argspec'] = dict(args=args, varargs=varargs,
779 varkw=varkw, defaults=defaults)
779 varkw=varkw, defaults=defaults)
780
780
781 return object_info(**out)
781 return object_info(**out)
782
782
783
783
784 def psearch(self,pattern,ns_table,ns_search=[],
784 def psearch(self,pattern,ns_table,ns_search=[],
785 ignore_case=False,show_all=False):
785 ignore_case=False,show_all=False):
786 """Search namespaces with wildcards for objects.
786 """Search namespaces with wildcards for objects.
787
787
788 Arguments:
788 Arguments:
789
789
790 - pattern: string containing shell-like wildcards to use in namespace
790 - pattern: string containing shell-like wildcards to use in namespace
791 searches and optionally a type specification to narrow the search to
791 searches and optionally a type specification to narrow the search to
792 objects of that type.
792 objects of that type.
793
793
794 - ns_table: dict of name->namespaces for search.
794 - ns_table: dict of name->namespaces for search.
795
795
796 Optional arguments:
796 Optional arguments:
797
797
798 - ns_search: list of namespace names to include in search.
798 - ns_search: list of namespace names to include in search.
799
799
800 - ignore_case(False): make the search case-insensitive.
800 - ignore_case(False): make the search case-insensitive.
801
801
802 - show_all(False): show all names, including those starting with
802 - show_all(False): show all names, including those starting with
803 underscores.
803 underscores.
804 """
804 """
805 #print 'ps pattern:<%r>' % pattern # dbg
805 #print 'ps pattern:<%r>' % pattern # dbg
806
806
807 # defaults
807 # defaults
808 type_pattern = 'all'
808 type_pattern = 'all'
809 filter = ''
809 filter = ''
810
810
811 cmds = pattern.split()
811 cmds = pattern.split()
812 len_cmds = len(cmds)
812 len_cmds = len(cmds)
813 if len_cmds == 1:
813 if len_cmds == 1:
814 # Only filter pattern given
814 # Only filter pattern given
815 filter = cmds[0]
815 filter = cmds[0]
816 elif len_cmds == 2:
816 elif len_cmds == 2:
817 # Both filter and type specified
817 # Both filter and type specified
818 filter,type_pattern = cmds
818 filter,type_pattern = cmds
819 else:
819 else:
820 raise ValueError('invalid argument string for psearch: <%s>' %
820 raise ValueError('invalid argument string for psearch: <%s>' %
821 pattern)
821 pattern)
822
822
823 # filter search namespaces
823 # filter search namespaces
824 for name in ns_search:
824 for name in ns_search:
825 if name not in ns_table:
825 if name not in ns_table:
826 raise ValueError('invalid namespace <%s>. Valid names: %s' %
826 raise ValueError('invalid namespace <%s>. Valid names: %s' %
827 (name,ns_table.keys()))
827 (name,ns_table.keys()))
828
828
829 #print 'type_pattern:',type_pattern # dbg
829 #print 'type_pattern:',type_pattern # dbg
830 search_result, namespaces_seen = set(), set()
830 search_result, namespaces_seen = set(), set()
831 for ns_name in ns_search:
831 for ns_name in ns_search:
832 ns = ns_table[ns_name]
832 ns = ns_table[ns_name]
833 # Normally, locals and globals are the same, so we just check one.
833 # Normally, locals and globals are the same, so we just check one.
834 if id(ns) in namespaces_seen:
834 if id(ns) in namespaces_seen:
835 continue
835 continue
836 namespaces_seen.add(id(ns))
836 namespaces_seen.add(id(ns))
837 tmp_res = list_namespace(ns, type_pattern, filter,
837 tmp_res = list_namespace(ns, type_pattern, filter,
838 ignore_case=ignore_case, show_all=show_all)
838 ignore_case=ignore_case, show_all=show_all)
839 search_result.update(tmp_res)
839 search_result.update(tmp_res)
840
840
841 page.page('\n'.join(sorted(search_result)))
841 page.page('\n'.join(sorted(search_result)))
General Comments 0
You need to be logged in to leave comments. Login now