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