##// END OF EJS Templates
Reduce unhelpful information shown by pinfo
Thomas Kluyver -
Show More
@@ -1,826 +1,841 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 fname = None
254 254 try:
255 255 fname = inspect.getabsfile(obj)
256 256 except TypeError:
257 257 # For an instance, the file that matters is where its class was
258 258 # declared.
259 259 if hasattr(obj, '__class__'):
260 260 try:
261 261 fname = inspect.getabsfile(obj.__class__)
262 262 except TypeError:
263 263 # Can happen for builtins
264 264 pass
265 265 except:
266 266 pass
267 267 return fname
268 268
269 269
270 270 def find_source_lines(obj):
271 271 """Find the line number in a file where an object was defined.
272 272
273 273 This is essentially a robust wrapper around `inspect.getsourcelines`.
274 274
275 275 Returns None if no file can be found.
276 276
277 277 Parameters
278 278 ----------
279 279 obj : any Python object
280 280
281 281 Returns
282 282 -------
283 283 lineno : int
284 284 The line number where the object definition starts.
285 285 """
286 286 # get source if obj was decorated with @decorator
287 287 if hasattr(obj, '__wrapped__'):
288 288 obj = obj.__wrapped__
289 289
290 290 try:
291 291 try:
292 292 lineno = inspect.getsourcelines(obj)[1]
293 293 except TypeError:
294 294 # For instances, try the class object like getsource() does
295 295 if hasattr(obj, '__class__'):
296 296 lineno = inspect.getsourcelines(obj.__class__)[1]
297 297 except:
298 298 return None
299 299
300 300 return lineno
301 301
302 302
303 303 class Inspector:
304 304 def __init__(self, color_table=InspectColors,
305 305 code_color_table=PyColorize.ANSICodeColors,
306 306 scheme='NoColor',
307 307 str_detail_level=0):
308 308 self.color_table = color_table
309 309 self.parser = PyColorize.Parser(code_color_table,out='str')
310 310 self.format = self.parser.format
311 311 self.str_detail_level = str_detail_level
312 312 self.set_active_scheme(scheme)
313 313
314 314 def _getdef(self,obj,oname=''):
315 315 """Return the definition header for any callable object.
316 316
317 317 If any exception is generated, None is returned instead and the
318 318 exception is suppressed."""
319 319
320 320 try:
321 321 # We need a plain string here, NOT unicode!
322 322 hdef = oname + inspect.formatargspec(*getargspec(obj))
323 323 return py3compat.unicode_to_str(hdef, 'ascii')
324 324 except:
325 325 return None
326 326
327 327 def __head(self,h):
328 328 """Return a header string with proper colors."""
329 329 return '%s%s%s' % (self.color_table.active_colors.header,h,
330 330 self.color_table.active_colors.normal)
331 331
332 332 def set_active_scheme(self, scheme):
333 333 self.color_table.set_active_scheme(scheme)
334 334 self.parser.color_table.set_active_scheme(scheme)
335 335
336 336 def noinfo(self, msg, oname):
337 337 """Generic message when no information is found."""
338 338 print 'No %s found' % msg,
339 339 if oname:
340 340 print 'for %s' % oname
341 341 else:
342 342 print
343 343
344 344 def pdef(self, obj, oname=''):
345 345 """Print the definition header for any callable object.
346 346
347 347 If the object is a class, print the constructor information."""
348 348
349 349 if not callable(obj):
350 350 print 'Object is not callable.'
351 351 return
352 352
353 353 header = ''
354 354
355 355 if inspect.isclass(obj):
356 356 header = self.__head('Class constructor information:\n')
357 357 obj = obj.__init__
358 358 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
359 359 obj = obj.__call__
360 360
361 361 output = self._getdef(obj,oname)
362 362 if output is None:
363 363 self.noinfo('definition header',oname)
364 364 else:
365 365 print >>io.stdout, header,self.format(output),
366 366
367 367 # In Python 3, all classes are new-style, so they all have __init__.
368 368 @skip_doctest_py3
369 369 def pdoc(self,obj,oname='',formatter = None):
370 370 """Print the docstring for any object.
371 371
372 372 Optional:
373 373 -formatter: a function to run the docstring through for specially
374 374 formatted docstrings.
375 375
376 376 Examples
377 377 --------
378 378
379 379 In [1]: class NoInit:
380 380 ...: pass
381 381
382 382 In [2]: class NoDoc:
383 383 ...: def __init__(self):
384 384 ...: pass
385 385
386 386 In [3]: %pdoc NoDoc
387 387 No documentation found for NoDoc
388 388
389 389 In [4]: %pdoc NoInit
390 390 No documentation found for NoInit
391 391
392 392 In [5]: obj = NoInit()
393 393
394 394 In [6]: %pdoc obj
395 395 No documentation found for obj
396 396
397 397 In [5]: obj2 = NoDoc()
398 398
399 399 In [6]: %pdoc obj2
400 400 No documentation found for obj2
401 401 """
402 402
403 403 head = self.__head # For convenience
404 404 lines = []
405 405 ds = getdoc(obj)
406 406 if formatter:
407 407 ds = formatter(ds)
408 408 if ds:
409 409 lines.append(head("Class Docstring:"))
410 410 lines.append(indent(ds))
411 411 if inspect.isclass(obj) and hasattr(obj, '__init__'):
412 412 init_ds = getdoc(obj.__init__)
413 413 if init_ds is not None:
414 414 lines.append(head("Constructor Docstring:"))
415 415 lines.append(indent(init_ds))
416 416 elif hasattr(obj,'__call__'):
417 417 call_ds = getdoc(obj.__call__)
418 418 if call_ds:
419 419 lines.append(head("Calling Docstring:"))
420 420 lines.append(indent(call_ds))
421 421
422 422 if not lines:
423 423 self.noinfo('documentation',oname)
424 424 else:
425 425 page.page('\n'.join(lines))
426 426
427 427 def psource(self,obj,oname=''):
428 428 """Print the source code for an object."""
429 429
430 430 # Flush the source cache because inspect can return out-of-date source
431 431 linecache.checkcache()
432 432 try:
433 433 src = getsource(obj)
434 434 except:
435 435 self.noinfo('source',oname)
436 436 else:
437 437 page.page(self.format(py3compat.unicode_to_str(src)))
438 438
439 439 def pfile(self, obj, oname=''):
440 440 """Show the whole file where an object was defined."""
441 441
442 442 lineno = find_source_lines(obj)
443 443 if lineno is None:
444 444 self.noinfo('file', oname)
445 445 return
446 446
447 447 ofile = find_file(obj)
448 448 # run contents of file through pager starting at line where the object
449 449 # is defined, as long as the file isn't binary and is actually on the
450 450 # filesystem.
451 451 if ofile.endswith(('.so', '.dll', '.pyd')):
452 452 print 'File %r is binary, not printing.' % ofile
453 453 elif not os.path.isfile(ofile):
454 454 print 'File %r does not exist, not printing.' % ofile
455 455 else:
456 456 # Print only text files, not extension binaries. Note that
457 457 # getsourcelines returns lineno with 1-offset and page() uses
458 458 # 0-offset, so we must adjust.
459 459 page.page(self.format(open(ofile).read()), lineno-1)
460 460
461 461 def _format_fields(self, fields, title_width=12):
462 462 """Formats a list of fields for display.
463 463
464 464 Parameters
465 465 ----------
466 466 fields : list
467 467 A list of 2-tuples: (field_title, field_content)
468 468 title_width : int
469 469 How many characters to pad titles to. Default 12.
470 470 """
471 471 out = []
472 472 header = self.__head
473 473 for title, content in fields:
474 474 if len(content.splitlines()) > 1:
475 475 title = header(title + ":") + "\n"
476 476 else:
477 477 title = header((title+":").ljust(title_width))
478 478 out.append(title + content)
479 479 return "\n".join(out)
480 480
481 481 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
482 482 pinfo_fields1 = [("Type", "type_name"),
483 ("Base Class", "base_class"),
484 ("String Form", "string_form"),
485 ("Namespace", "namespace"),
486 ("Length", "length"),
483 ]
484
485 pinfo_fields2 = [("String Form", "string_form"),
486 ]
487
488 pinfo_fields3 = [("Length", "length"),
487 489 ("File", "file"),
488 ("Definition", "definition")]
490 ("Definition", "definition"),
491 ]
489 492
490 493 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
491 494 ("Constructor Docstring","init_docstring"),
492 495 ("Call def", "call_def"),
493 496 ("Call docstring", "call_docstring")]
494 497
495 498 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
496 499 """Show detailed information about an object.
497 500
498 501 Optional arguments:
499 502
500 503 - oname: name of the variable pointing to the object.
501 504
502 505 - formatter: special formatter for docstrings (see pdoc)
503 506
504 507 - info: a structure with some information fields which may have been
505 508 precomputed already.
506 509
507 510 - detail_level: if set to 1, more information is given.
508 511 """
509 512 info = self.info(obj, oname=oname, formatter=formatter,
510 513 info=info, detail_level=detail_level)
511 514 displayfields = []
512 for title, key in self.pinfo_fields1:
513 field = info[key]
514 if field is not None:
515 displayfields.append((title, field.rstrip()))
515 def add_fields(fields):
516 for title, key in fields:
517 field = info[key]
518 if field is not None:
519 displayfields.append((title, field.rstrip()))
520
521 add_fields(self.pinfo_fields1)
522
523 # Base class for old-style instances
524 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
525 displayfield.append(("Base Class", info['base_class'].rstrip()))
526
527 add_fields(self.pinfo_fields2)
528
529 # Namespace
530 if info['namespace'] != 'Interactive':
531 displayfield.append(("Namespace", info['namespace'].rstrip()))
516 532
533 add_fields(self.pinfo_fields3)
534
517 535 # Source or docstring, depending on detail level and whether
518 536 # source found.
519 537 if detail_level > 0 and info['source'] is not None:
520 538 displayfields.append(("Source", self.format(py3compat.cast_bytes_py2(info['source']))))
521 539 elif info['docstring'] is not None:
522 540 displayfields.append(("Docstring", info["docstring"]))
523 541
524 542 # Constructor info for classes
525 543 if info['isclass']:
526 544 if info['init_definition'] or info['init_docstring']:
527 545 displayfields.append(("Constructor information", ""))
528 546 if info['init_definition'] is not None:
529 547 displayfields.append((" Definition",
530 548 info['init_definition'].rstrip()))
531 549 if info['init_docstring'] is not None:
532 550 displayfields.append((" Docstring",
533 551 indent(info['init_docstring'])))
534 552
535 553 # Info for objects:
536 554 else:
537 for title, key in self.pinfo_fields_obj:
538 field = info[key]
539 if field is not None:
540 displayfields.append((title, field.rstrip()))
555 add_fields(self.pinfo_fields_obj)
541 556
542 557 # Finally send to printer/pager:
543 558 if displayfields:
544 559 page.page(self._format_fields(displayfields))
545 560
546 561 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
547 562 """Compute a dict with detailed information about an object.
548 563
549 564 Optional arguments:
550 565
551 566 - oname: name of the variable pointing to the object.
552 567
553 568 - formatter: special formatter for docstrings (see pdoc)
554 569
555 570 - info: a structure with some information fields which may have been
556 571 precomputed already.
557 572
558 573 - detail_level: if set to 1, more information is given.
559 574 """
560 575
561 576 obj_type = type(obj)
562 577
563 578 header = self.__head
564 579 if info is None:
565 580 ismagic = 0
566 581 isalias = 0
567 582 ospace = ''
568 583 else:
569 584 ismagic = info.ismagic
570 585 isalias = info.isalias
571 586 ospace = info.namespace
572 587
573 588 # Get docstring, special-casing aliases:
574 589 if isalias:
575 590 if not callable(obj):
576 591 try:
577 592 ds = "Alias to the system command:\n %s" % obj[1]
578 593 except:
579 594 ds = "Alias: " + str(obj)
580 595 else:
581 596 ds = "Alias to " + str(obj)
582 597 if obj.__doc__:
583 598 ds += "\nDocstring:\n" + obj.__doc__
584 599 else:
585 600 ds = getdoc(obj)
586 601 if ds is None:
587 602 ds = '<no docstring>'
588 603 if formatter is not None:
589 604 ds = formatter(ds)
590 605
591 606 # store output in a dict, we initialize it here and fill it as we go
592 607 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
593 608
594 609 string_max = 200 # max size of strings to show (snipped if longer)
595 610 shalf = int((string_max -5)/2)
596 611
597 612 if ismagic:
598 613 obj_type_name = 'Magic function'
599 614 elif isalias:
600 615 obj_type_name = 'System alias'
601 616 else:
602 617 obj_type_name = obj_type.__name__
603 618 out['type_name'] = obj_type_name
604 619
605 620 try:
606 621 bclass = obj.__class__
607 622 out['base_class'] = str(bclass)
608 623 except: pass
609 624
610 625 # String form, but snip if too long in ? form (full in ??)
611 626 if detail_level >= self.str_detail_level:
612 627 try:
613 628 ostr = str(obj)
614 629 str_head = 'string_form'
615 630 if not detail_level and len(ostr)>string_max:
616 631 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
617 632 ostr = ("\n" + " " * len(str_head.expandtabs())).\
618 633 join(q.strip() for q in ostr.split("\n"))
619 634 out[str_head] = ostr
620 635 except:
621 636 pass
622 637
623 638 if ospace:
624 639 out['namespace'] = ospace
625 640
626 641 # Length (for strings and lists)
627 642 try:
628 643 out['length'] = str(len(obj))
629 644 except: pass
630 645
631 646 # Filename where object was defined
632 647 binary_file = False
633 648 fname = find_file(obj)
634 649 if fname is None:
635 650 # if anything goes wrong, we don't want to show source, so it's as
636 651 # if the file was binary
637 652 binary_file = True
638 653 else:
639 654 if fname.endswith(('.so', '.dll', '.pyd')):
640 655 binary_file = True
641 656 elif fname.endswith('<string>'):
642 657 fname = 'Dynamically generated function. No source code available.'
643 658 out['file'] = fname
644 659
645 660 # reconstruct the function definition and print it:
646 661 defln = self._getdef(obj, oname)
647 662 if defln:
648 663 out['definition'] = self.format(defln)
649 664
650 665 # Docstrings only in detail 0 mode, since source contains them (we
651 666 # avoid repetitions). If source fails, we add them back, see below.
652 667 if ds and detail_level == 0:
653 668 out['docstring'] = ds
654 669
655 670 # Original source code for any callable
656 671 if detail_level:
657 672 # Flush the source cache because inspect can return out-of-date
658 673 # source
659 674 linecache.checkcache()
660 675 source = None
661 676 try:
662 677 try:
663 678 source = getsource(obj, binary_file)
664 679 except TypeError:
665 680 if hasattr(obj, '__class__'):
666 681 source = getsource(obj.__class__, binary_file)
667 682 if source is not None:
668 683 out['source'] = source.rstrip()
669 684 except Exception:
670 685 pass
671 686
672 687 if ds and source is None:
673 688 out['docstring'] = ds
674 689
675 690
676 691 # Constructor docstring for classes
677 692 if inspect.isclass(obj):
678 693 out['isclass'] = True
679 694 # reconstruct the function definition and print it:
680 695 try:
681 696 obj_init = obj.__init__
682 697 except AttributeError:
683 698 init_def = init_ds = None
684 699 else:
685 700 init_def = self._getdef(obj_init,oname)
686 701 init_ds = getdoc(obj_init)
687 702 # Skip Python's auto-generated docstrings
688 703 if init_ds and \
689 704 init_ds.startswith('x.__init__(...) initializes'):
690 705 init_ds = None
691 706
692 707 if init_def or init_ds:
693 708 if init_def:
694 709 out['init_definition'] = self.format(init_def)
695 710 if init_ds:
696 711 out['init_docstring'] = init_ds
697 712
698 713 # and class docstring for instances:
699 714 else:
700 715 # First, check whether the instance docstring is identical to the
701 716 # class one, and print it separately if they don't coincide. In
702 717 # most cases they will, but it's nice to print all the info for
703 718 # objects which use instance-customized docstrings.
704 719 if ds:
705 720 try:
706 721 cls = getattr(obj,'__class__')
707 722 except:
708 723 class_ds = None
709 724 else:
710 725 class_ds = getdoc(cls)
711 726 # Skip Python's auto-generated docstrings
712 727 if class_ds and \
713 728 (class_ds.startswith('function(code, globals[,') or \
714 729 class_ds.startswith('instancemethod(function, instance,') or \
715 730 class_ds.startswith('module(name[,') ):
716 731 class_ds = None
717 732 if class_ds and ds != class_ds:
718 733 out['class_docstring'] = class_ds
719 734
720 735 # Next, try to show constructor docstrings
721 736 try:
722 737 init_ds = getdoc(obj.__init__)
723 738 # Skip Python's auto-generated docstrings
724 739 if init_ds and \
725 740 init_ds.startswith('x.__init__(...) initializes'):
726 741 init_ds = None
727 742 except AttributeError:
728 743 init_ds = None
729 744 if init_ds:
730 745 out['init_docstring'] = init_ds
731 746
732 747 # Call form docstring for callable instances
733 748 if hasattr(obj, '__call__'):
734 749 call_def = self._getdef(obj.__call__, oname)
735 750 if call_def is not None:
736 751 out['call_def'] = self.format(call_def)
737 752 call_ds = getdoc(obj.__call__)
738 753 # Skip Python's auto-generated docstrings
739 754 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
740 755 call_ds = None
741 756 if call_ds:
742 757 out['call_docstring'] = call_ds
743 758
744 759 # Compute the object's argspec as a callable. The key is to decide
745 760 # whether to pull it from the object itself, from its __init__ or
746 761 # from its __call__ method.
747 762
748 763 if inspect.isclass(obj):
749 764 # Old-style classes need not have an __init__
750 765 callable_obj = getattr(obj, "__init__", None)
751 766 elif callable(obj):
752 767 callable_obj = obj
753 768 else:
754 769 callable_obj = None
755 770
756 771 if callable_obj:
757 772 try:
758 773 args, varargs, varkw, defaults = getargspec(callable_obj)
759 774 except (TypeError, AttributeError):
760 775 # For extensions/builtins we can't retrieve the argspec
761 776 pass
762 777 else:
763 778 out['argspec'] = dict(args=args, varargs=varargs,
764 779 varkw=varkw, defaults=defaults)
765 780
766 781 return object_info(**out)
767 782
768 783
769 784 def psearch(self,pattern,ns_table,ns_search=[],
770 785 ignore_case=False,show_all=False):
771 786 """Search namespaces with wildcards for objects.
772 787
773 788 Arguments:
774 789
775 790 - pattern: string containing shell-like wildcards to use in namespace
776 791 searches and optionally a type specification to narrow the search to
777 792 objects of that type.
778 793
779 794 - ns_table: dict of name->namespaces for search.
780 795
781 796 Optional arguments:
782 797
783 798 - ns_search: list of namespace names to include in search.
784 799
785 800 - ignore_case(False): make the search case-insensitive.
786 801
787 802 - show_all(False): show all names, including those starting with
788 803 underscores.
789 804 """
790 805 #print 'ps pattern:<%r>' % pattern # dbg
791 806
792 807 # defaults
793 808 type_pattern = 'all'
794 809 filter = ''
795 810
796 811 cmds = pattern.split()
797 812 len_cmds = len(cmds)
798 813 if len_cmds == 1:
799 814 # Only filter pattern given
800 815 filter = cmds[0]
801 816 elif len_cmds == 2:
802 817 # Both filter and type specified
803 818 filter,type_pattern = cmds
804 819 else:
805 820 raise ValueError('invalid argument string for psearch: <%s>' %
806 821 pattern)
807 822
808 823 # filter search namespaces
809 824 for name in ns_search:
810 825 if name not in ns_table:
811 826 raise ValueError('invalid namespace <%s>. Valid names: %s' %
812 827 (name,ns_table.keys()))
813 828
814 829 #print 'type_pattern:',type_pattern # dbg
815 830 search_result, namespaces_seen = set(), set()
816 831 for ns_name in ns_search:
817 832 ns = ns_table[ns_name]
818 833 # Normally, locals and globals are the same, so we just check one.
819 834 if id(ns) in namespaces_seen:
820 835 continue
821 836 namespaces_seen.add(id(ns))
822 837 tmp_res = list_namespace(ns, type_pattern, filter,
823 838 ignore_case=ignore_case, show_all=show_all)
824 839 search_result.update(tmp_res)
825 840
826 841 page.page('\n'.join(sorted(search_result)))
General Comments 0
You need to be logged in to leave comments. Login now