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