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