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