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