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