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