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