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