##// END OF EJS Templates
Better check for missing source in Inspector.info()
Thomas Kluyver -
Show More
@@ -1,737 +1,738 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 399 pinfo_fields_obj = [("Constructor Docstring","init_docstring"),
400 400 ("Call def", "call_def"),
401 401 ("Call docstring", "call_docstring")]
402 402
403 403 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
404 404 """Show detailed information about an object.
405 405
406 406 Optional arguments:
407 407
408 408 - oname: name of the variable pointing to the object.
409 409
410 410 - formatter: special formatter for docstrings (see pdoc)
411 411
412 412 - info: a structure with some information fields which may have been
413 413 precomputed already.
414 414
415 415 - detail_level: if set to 1, more information is given.
416 416 """
417 417 info = self.info(obj, oname=oname, formatter=formatter,
418 418 info=info, detail_level=detail_level)
419 419 displayfields = []
420 420 for title, key in self.pinfo_fields1:
421 421 field = info[key]
422 422 if field is not None:
423 423 displayfields.append((title, field.rstrip()))
424 424
425 425 # Source or docstring, depending on detail level and whether
426 426 # source found.
427 427 if detail_level > 0 and info['source'] is not None:
428 428 displayfields.append(("Source", info['source']))
429 429 elif info['docstring'] is not None:
430 430 displayfields.append(("Docstring", info["docstring"]))
431 431
432 432 # Constructor info for classes
433 433 if info['isclass']:
434 434 if info['init_definition'] or info['init_docstring']:
435 435 displayfields.append(("Constructor information", ""))
436 436 if info['init_definition'] is not None:
437 437 displayfields.append((" Definition",
438 438 info['init_definition'].rstrip()))
439 439 if info['init_docstring'] is not None:
440 440 displayfields.append((" Docstring",
441 441 indent(info['init_docstring'])))
442 442
443 443 # Info for objects:
444 444 else:
445 445 for title, key in self.pinfo_fields_obj:
446 446 field = info[key]
447 447 if field is not None:
448 448 displayfields.append((title, field.rstrip()))
449 449
450 450 # Finally send to printer/pager:
451 451 if displayfields:
452 452 page.page(self._format_fields(displayfields))
453 453
454 454 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
455 455 """Compute a dict with detailed information about an object.
456 456
457 457 Optional arguments:
458 458
459 459 - oname: name of the variable pointing to the object.
460 460
461 461 - formatter: special formatter for docstrings (see pdoc)
462 462
463 463 - info: a structure with some information fields which may have been
464 464 precomputed already.
465 465
466 466 - detail_level: if set to 1, more information is given.
467 467 """
468 468
469 469 obj_type = type(obj)
470 470
471 471 header = self.__head
472 472 if info is None:
473 473 ismagic = 0
474 474 isalias = 0
475 475 ospace = ''
476 476 else:
477 477 ismagic = info.ismagic
478 478 isalias = info.isalias
479 479 ospace = info.namespace
480 480
481 481 # Get docstring, special-casing aliases:
482 482 if isalias:
483 483 if not callable(obj):
484 484 try:
485 485 ds = "Alias to the system command:\n %s" % obj[1]
486 486 except:
487 487 ds = "Alias: " + str(obj)
488 488 else:
489 489 ds = "Alias to " + str(obj)
490 490 if obj.__doc__:
491 491 ds += "\nDocstring:\n" + obj.__doc__
492 492 else:
493 493 ds = getdoc(obj)
494 494 if ds is None:
495 495 ds = '<no docstring>'
496 496 if formatter is not None:
497 497 ds = formatter(ds)
498 498
499 499 # store output in a dict, we initialize it here and fill it as we go
500 500 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
501 501
502 502 string_max = 200 # max size of strings to show (snipped if longer)
503 503 shalf = int((string_max -5)/2)
504 504
505 505 if ismagic:
506 506 obj_type_name = 'Magic function'
507 507 elif isalias:
508 508 obj_type_name = 'System alias'
509 509 else:
510 510 obj_type_name = obj_type.__name__
511 511 out['type_name'] = obj_type_name
512 512
513 513 try:
514 514 bclass = obj.__class__
515 515 out['base_class'] = str(bclass)
516 516 except: pass
517 517
518 518 # String form, but snip if too long in ? form (full in ??)
519 519 if detail_level >= self.str_detail_level:
520 520 try:
521 521 ostr = str(obj)
522 522 str_head = 'string_form'
523 523 if not detail_level and len(ostr)>string_max:
524 524 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
525 525 ostr = ("\n" + " " * len(str_head.expandtabs())).\
526 526 join(q.strip() for q in ostr.split("\n"))
527 527 out[str_head] = ostr
528 528 except:
529 529 pass
530 530
531 531 if ospace:
532 532 out['namespace'] = ospace
533 533
534 534 # Length (for strings and lists)
535 535 try:
536 536 out['length'] = str(len(obj))
537 537 except: pass
538 538
539 539 # Filename where object was defined
540 540 binary_file = False
541 541 try:
542 542 try:
543 543 fname = inspect.getabsfile(obj)
544 544 except TypeError:
545 545 # For an instance, the file that matters is where its class was
546 546 # declared.
547 547 if hasattr(obj,'__class__'):
548 548 fname = inspect.getabsfile(obj.__class__)
549 549 if fname.endswith('<string>'):
550 550 fname = 'Dynamically generated function. No source code available.'
551 551 if (fname.endswith('.so') or fname.endswith('.dll')):
552 552 binary_file = True
553 553 out['file'] = fname
554 554 except:
555 555 # if anything goes wrong, we don't want to show source, so it's as
556 556 # if the file was binary
557 557 binary_file = True
558 558
559 559 # reconstruct the function definition and print it:
560 560 defln = self._getdef(obj, oname)
561 561 if defln:
562 562 out['definition'] = self.format(defln)
563 563
564 564 # Docstrings only in detail 0 mode, since source contains them (we
565 565 # avoid repetitions). If source fails, we add them back, see below.
566 566 if ds and detail_level == 0:
567 567 out['docstring'] = ds
568 568
569 569 # Original source code for any callable
570 570 if detail_level:
571 571 # Flush the source cache because inspect can return out-of-date
572 572 # source
573 573 linecache.checkcache()
574 source_success = False
574 source = None
575 575 try:
576 576 try:
577 577 src = getsource(obj,binary_file)
578 578 except TypeError:
579 579 if hasattr(obj,'__class__'):
580 580 src = getsource(obj.__class__,binary_file)
581 581 if src is not None:
582 582 source = self.format(src)
583 583 out['source'] = source.rstrip()
584 source_success = True
585 584 except Exception:
586 if ds:
585 pass
586
587 if ds and source is None:
587 588 out['docstring'] = ds
588 589
589 590
590 591 # Constructor docstring for classes
591 592 if inspect.isclass(obj):
592 593 out['isclass'] = True
593 594 # reconstruct the function definition and print it:
594 595 try:
595 596 obj_init = obj.__init__
596 597 except AttributeError:
597 598 init_def = init_ds = None
598 599 else:
599 600 init_def = self._getdef(obj_init,oname)
600 601 init_ds = getdoc(obj_init)
601 602 # Skip Python's auto-generated docstrings
602 603 if init_ds and \
603 604 init_ds.startswith('x.__init__(...) initializes'):
604 605 init_ds = None
605 606
606 607 if init_def or init_ds:
607 608 if init_def:
608 609 out['init_definition'] = self.format(init_def)
609 610 if init_ds:
610 611 out['init_docstring'] = init_ds
611 612
612 613 # and class docstring for instances:
613 614 else:
614 615 # First, check whether the instance docstring is identical to the
615 616 # class one, and print it separately if they don't coincide. In
616 617 # most cases they will, but it's nice to print all the info for
617 618 # objects which use instance-customized docstrings.
618 619 if ds:
619 620 try:
620 621 cls = getattr(obj,'__class__')
621 622 except:
622 623 class_ds = None
623 624 else:
624 625 class_ds = getdoc(cls)
625 626 # Skip Python's auto-generated docstrings
626 627 if class_ds and \
627 628 (class_ds.startswith('function(code, globals[,') or \
628 629 class_ds.startswith('instancemethod(function, instance,') or \
629 630 class_ds.startswith('module(name[,') ):
630 631 class_ds = None
631 632 if class_ds and ds != class_ds:
632 633 out['class_docstring'] = class_ds
633 634
634 635 # Next, try to show constructor docstrings
635 636 try:
636 637 init_ds = getdoc(obj.__init__)
637 638 # Skip Python's auto-generated docstrings
638 639 if init_ds and \
639 640 init_ds.startswith('x.__init__(...) initializes'):
640 641 init_ds = None
641 642 except AttributeError:
642 643 init_ds = None
643 644 if init_ds:
644 645 out['init_docstring'] = init_ds
645 646
646 647 # Call form docstring for callable instances
647 648 if hasattr(obj, '__call__'):
648 649 call_def = self._getdef(obj.__call__, oname)
649 650 if call_def is not None:
650 651 out['call_def'] = self.format(call_def)
651 652 call_ds = getdoc(obj.__call__)
652 653 # Skip Python's auto-generated docstrings
653 654 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
654 655 call_ds = None
655 656 if call_ds:
656 657 out['call_docstring'] = call_ds
657 658
658 659 # Compute the object's argspec as a callable. The key is to decide
659 660 # whether to pull it from the object itself, from its __init__ or
660 661 # from its __call__ method.
661 662
662 663 if inspect.isclass(obj):
663 664 callable_obj = obj.__init__
664 665 elif callable(obj):
665 666 callable_obj = obj
666 667 else:
667 668 callable_obj = None
668 669
669 670 if callable_obj:
670 671 try:
671 672 args, varargs, varkw, defaults = getargspec(callable_obj)
672 673 except (TypeError, AttributeError):
673 674 # For extensions/builtins we can't retrieve the argspec
674 675 pass
675 676 else:
676 677 out['argspec'] = dict(args=args, varargs=varargs,
677 678 varkw=varkw, defaults=defaults)
678 679
679 680 return object_info(**out)
680 681
681 682
682 683 def psearch(self,pattern,ns_table,ns_search=[],
683 684 ignore_case=False,show_all=False):
684 685 """Search namespaces with wildcards for objects.
685 686
686 687 Arguments:
687 688
688 689 - pattern: string containing shell-like wildcards to use in namespace
689 690 searches and optionally a type specification to narrow the search to
690 691 objects of that type.
691 692
692 693 - ns_table: dict of name->namespaces for search.
693 694
694 695 Optional arguments:
695 696
696 697 - ns_search: list of namespace names to include in search.
697 698
698 699 - ignore_case(False): make the search case-insensitive.
699 700
700 701 - show_all(False): show all names, including those starting with
701 702 underscores.
702 703 """
703 704 #print 'ps pattern:<%r>' % pattern # dbg
704 705
705 706 # defaults
706 707 type_pattern = 'all'
707 708 filter = ''
708 709
709 710 cmds = pattern.split()
710 711 len_cmds = len(cmds)
711 712 if len_cmds == 1:
712 713 # Only filter pattern given
713 714 filter = cmds[0]
714 715 elif len_cmds == 2:
715 716 # Both filter and type specified
716 717 filter,type_pattern = cmds
717 718 else:
718 719 raise ValueError('invalid argument string for psearch: <%s>' %
719 720 pattern)
720 721
721 722 # filter search namespaces
722 723 for name in ns_search:
723 724 if name not in ns_table:
724 725 raise ValueError('invalid namespace <%s>. Valid names: %s' %
725 726 (name,ns_table.keys()))
726 727
727 728 #print 'type_pattern:',type_pattern # dbg
728 729 search_result = []
729 730 for ns_name in ns_search:
730 731 ns = ns_table[ns_name]
731 732 tmp_res = list(list_namespace(ns,type_pattern,filter,
732 733 ignore_case=ignore_case,
733 734 show_all=show_all))
734 735 search_result.extend(tmp_res)
735 736 search_result.sort()
736 737
737 738 page.page('\n'.join(search_result))
General Comments 0
You need to be logged in to leave comments. Login now