##// END OF EJS Templates
rehighlight in html
Matthias Bussonnier -
Show More
@@ -1,978 +1,985 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 warnings
21 21 import os
22 22 from textwrap import dedent
23 23 import types
24 24 import io as stdlib_io
25 25
26 26 try:
27 27 from itertools import izip_longest
28 28 except ImportError:
29 29 from itertools import zip_longest as izip_longest
30 30
31 31 # IPython's own
32 32 from IPython.core import page
33 33 from IPython.lib.pretty import pretty
34 34 from IPython.testing.skipdoctest import skip_doctest_py3
35 35 from IPython.utils import PyColorize
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 """
118 118 # Allow objects to offer customized documentation via a getdoc method:
119 119 try:
120 120 ds = obj.getdoc()
121 121 except Exception:
122 122 pass
123 123 else:
124 124 # if we get extra info, we add it to the normal docstring.
125 125 if isinstance(ds, string_types):
126 126 return inspect.cleandoc(ds)
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 # extensions modules.
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 from pygments import highlight
369 from pygments.lexers import PythonLexer
370 from pygments.formatters import HtmlFormatter
371
372 def pylight(code):
373 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
374
368 375
369 376 class Inspector(Colorable):
370 377
371 378 def __init__(self, color_table=InspectColors,
372 379 code_color_table=PyColorize.ANSICodeColors,
373 380 scheme='NoColor',
374 381 str_detail_level=0,
375 382 parent=None, config=None):
376 383 super(Inspector, self).__init__(parent=parent, config=config)
377 384 self.color_table = color_table
378 385 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
379 386 self.format = self.parser.format
380 387 self.str_detail_level = str_detail_level
381 388 self.set_active_scheme(scheme)
382 389
383 390 def _getdef(self,obj,oname=''):
384 391 """Return the call signature for any callable object.
385 392
386 393 If any exception is generated, None is returned instead and the
387 394 exception is suppressed."""
388 395 try:
389 396 hdef = oname + str(signature(obj))
390 397 return cast_unicode(hdef)
391 398 except:
392 399 return None
393 400
394 401 def __head(self,h):
395 402 """Return a header string with proper colors."""
396 403 return '%s%s%s' % (self.color_table.active_colors.header,h,
397 404 self.color_table.active_colors.normal)
398 405
399 406 def set_active_scheme(self, scheme):
400 407 self.color_table.set_active_scheme(scheme)
401 408 self.parser.color_table.set_active_scheme(scheme)
402 409
403 410 def noinfo(self, msg, oname):
404 411 """Generic message when no information is found."""
405 412 print('No %s found' % msg, end=' ')
406 413 if oname:
407 414 print('for %s' % oname)
408 415 else:
409 416 print()
410 417
411 418 def pdef(self, obj, oname=''):
412 419 """Print the call signature for any callable object.
413 420
414 421 If the object is a class, print the constructor information."""
415 422
416 423 if not callable(obj):
417 424 print('Object is not callable.')
418 425 return
419 426
420 427 header = ''
421 428
422 429 if inspect.isclass(obj):
423 430 header = self.__head('Class constructor information:\n')
424 431 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
425 432 obj = obj.__call__
426 433
427 434 output = self._getdef(obj,oname)
428 435 if output is None:
429 436 self.noinfo('definition header',oname)
430 437 else:
431 438 print(header,self.format(output), end=' ')
432 439
433 440 # In Python 3, all classes are new-style, so they all have __init__.
434 441 @skip_doctest_py3
435 442 def pdoc(self, obj, oname='', formatter=None):
436 443 """Print the docstring for any object.
437 444
438 445 Optional:
439 446 -formatter: a function to run the docstring through for specially
440 447 formatted docstrings.
441 448
442 449 Examples
443 450 --------
444 451
445 452 In [1]: class NoInit:
446 453 ...: pass
447 454
448 455 In [2]: class NoDoc:
449 456 ...: def __init__(self):
450 457 ...: pass
451 458
452 459 In [3]: %pdoc NoDoc
453 460 No documentation found for NoDoc
454 461
455 462 In [4]: %pdoc NoInit
456 463 No documentation found for NoInit
457 464
458 465 In [5]: obj = NoInit()
459 466
460 467 In [6]: %pdoc obj
461 468 No documentation found for obj
462 469
463 470 In [5]: obj2 = NoDoc()
464 471
465 472 In [6]: %pdoc obj2
466 473 No documentation found for obj2
467 474 """
468 475
469 476 head = self.__head # For convenience
470 477 lines = []
471 478 ds = getdoc(obj)
472 479 if formatter:
473 ds = formatter(ds)
480 ds = formatter(ds).get('plain/text', ds)
474 481 if ds:
475 482 lines.append(head("Class docstring:"))
476 483 lines.append(indent(ds))
477 484 if inspect.isclass(obj) and hasattr(obj, '__init__'):
478 485 init_ds = getdoc(obj.__init__)
479 486 if init_ds is not None:
480 487 lines.append(head("Init docstring:"))
481 488 lines.append(indent(init_ds))
482 489 elif hasattr(obj,'__call__'):
483 490 call_ds = getdoc(obj.__call__)
484 491 if call_ds:
485 492 lines.append(head("Call docstring:"))
486 493 lines.append(indent(call_ds))
487 494
488 495 if not lines:
489 496 self.noinfo('documentation',oname)
490 497 else:
491 498 page.page('\n'.join(lines))
492 499
493 500 def psource(self, obj, oname=''):
494 501 """Print the source code for an object."""
495 502
496 503 # Flush the source cache because inspect can return out-of-date source
497 504 linecache.checkcache()
498 505 try:
499 506 src = getsource(obj, oname=oname)
500 507 except Exception:
501 508 src = None
502 509
503 510 if src is None:
504 511 self.noinfo('source', oname)
505 512 else:
506 513 page.page(self.format(src))
507 514
508 515 def pfile(self, obj, oname=''):
509 516 """Show the whole file where an object was defined."""
510 517
511 518 lineno = find_source_lines(obj)
512 519 if lineno is None:
513 520 self.noinfo('file', oname)
514 521 return
515 522
516 523 ofile = find_file(obj)
517 524 # run contents of file through pager starting at line where the object
518 525 # is defined, as long as the file isn't binary and is actually on the
519 526 # filesystem.
520 527 if ofile.endswith(('.so', '.dll', '.pyd')):
521 528 print('File %r is binary, not printing.' % ofile)
522 529 elif not os.path.isfile(ofile):
523 530 print('File %r does not exist, not printing.' % ofile)
524 531 else:
525 532 # Print only text files, not extension binaries. Note that
526 533 # getsourcelines returns lineno with 1-offset and page() uses
527 534 # 0-offset, so we must adjust.
528 535 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
529 536
530 537 def _format_fields(self, fields, title_width=0):
531 538 """Formats a list of fields for display.
532 539
533 540 Parameters
534 541 ----------
535 542 fields : list
536 543 A list of 2-tuples: (field_title, field_content)
537 544 title_width : int
538 545 How many characters to pad titles to. Default to longest title.
539 546 """
540 547 out = []
541 548 header = self.__head
542 549 if title_width == 0:
543 550 title_width = max(len(title) + 2 for title, _ in fields)
544 551 for title, content in fields:
545 552 if len(content.splitlines()) > 1:
546 553 title = header(title + ':') + '\n'
547 554 else:
548 555 title = header((title + ':').ljust(title_width))
549 556 out.append(cast_unicode(title) + cast_unicode(content))
550 557 return "\n".join(out)
551 558
552 559 def _mime_format(self, text, formatter=None):
553 560 """Return a mime bundle representation of the input text.
554 561
555 562 - if `formatter` is None, the returned mime bundle has
556 563 a `text/plain` field, with the input text.
557 564 a `text/html` field with a `<pre>` tag containing the input text.
558 565
559 566 - if `formatter` is not None, it must be a callable transforming the
560 567 input text into a mime bundle. Default values for `text/plain` and
561 568 `text/html` representations are the ones described above.
562 569
563 570 Note:
564 571
565 572 Formatters returning strings are supported but this behavior is deprecated.
566 573
567 574 """
568 575 text = cast_unicode(text)
569 576 defaults = {
570 577 'text/plain': text,
571 578 'text/html': '<pre>' + text + '</pre>'
572 579 }
573 580
574 581 if formatter is None:
575 582 return defaults
576 583 else:
577 584 formatted = formatter(text)
578 585
579 586 if not isinstance(formatted, dict):
580 587 # Handle the deprecated behavior of a formatter returning
581 588 # a string instead of a mime bundle.
582 589 return {
583 590 'text/plain': formatted,
584 591 'text/html': '<pre>' + formatted + '</pre>'
585 592 }
586 593
587 594 else:
588 595 return dict(defaults, **formatted)
589 596
590 597 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
591 598 """Retrieve an info dict and format it."""
592 599
593 600 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
594 601
595 602 mime = {
596 603 'text/plain': '',
597 604 'text/html': '',
598 605 }
599 606
600 607 def append_field(bundle, title, key, formatter=None):
601 608 field = info[key]
602 609 if field is not None:
603 610 formatted_field = self._mime_format(field, formatter)
604 611 bundle['text/plain'] += self.__head(title) + ':\n' + formatted_field['text/plain'] + '\n'
605 612 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
606 613
607 614 def code_formatter(text):
608 615 return {
609 616 'text/plain': self.format(text),
610 'text/html': '<pre>' + text + '</pre>'
617 'text/html': pylight(text)
611 618 }
612 619
613 620 if info['isalias']:
614 621 append_field(mime, 'Repr', 'string_form')
615 622
616 623 elif info['ismagic']:
617 624 if detail_level > 0:
618 625 append_field(mime, 'Source', 'source', code_formatter)
619 626 else:
620 627 append_field(mime, 'Docstring', 'docstring', formatter)
621 628 append_field(mime, 'File', 'file')
622 629
623 630 elif info['isclass'] or is_simple_callable(obj):
624 631 # Functions, methods, classes
625 632 append_field(mime, 'Signature', 'definition', code_formatter)
626 633 append_field(mime, 'Init signature', 'init_definition', code_formatter)
627 634 if detail_level > 0:
628 635 append_field(mime, 'Source', 'source', code_formatter)
629 636 else:
630 637 append_field(mime, 'Docstring', 'docstring', formatter)
631 638 append_field(mime, 'Init docstring', 'init_docstring', formatter)
632 639
633 640 append_field(mime, 'File', 'file')
634 641 append_field(mime, 'Type', 'type_name')
635 642
636 643 else:
637 644 # General Python objects
638 645 append_field(mime, 'Type', 'type_name')
639 646
640 647 # Base class for old-style instances
641 648 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
642 649 append_field(mime, 'Base Class', 'base_class')
643 650
644 651 append_field(mime, 'String form', 'string_form')
645 652
646 653 # Namespace
647 654 if info['namespace'] != 'Interactive':
648 655 append_field(mime, 'Namespace', 'namespace')
649 656
650 657 append_field(mime, 'Length', 'length')
651 658 append_field(mime, 'File', 'file'),
652 659 append_field(mime, 'Signature', 'definition', code_formatter)
653 660
654 661 # Source or docstring, depending on detail level and whether
655 662 # source found.
656 663 if detail_level > 0:
657 664 append_field(mime, 'Source', 'source', code_formatter)
658 665 else:
659 666 append_field(mime, 'Docstring', 'docstring', formatter)
660 667
661 668 append_field(mime, 'Class docstring', 'class_docstring', formatter)
662 669 append_field(mime, 'Init docstring', 'init_docstring', formatter)
663 670 append_field(mime, 'Call signature', 'call_def', code_formatter)
664 671 append_field(mime, 'Call docstring', 'call_docstring', formatter)
665 672
666 673 return mime
667 674
668 675 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
669 676 """Show detailed information about an object.
670 677
671 678 Optional arguments:
672 679
673 680 - oname: name of the variable pointing to the object.
674 681
675 682 - formatter: callable (optional)
676 683 A special formatter for docstrings.
677 684
678 685 The formatter is a callable that takes a string as an input
679 686 and returns either a formatted string or a mime type bundle
680 687 in the form of a dictionnary.
681 688
682 689 Although the support of custom formatter returning a string
683 690 instead of a mime type bundle is deprecated.
684 691
685 692 - info: a structure with some information fields which may have been
686 693 precomputed already.
687 694
688 695 - detail_level: if set to 1, more information is given.
689 696 """
690 697 info = self._get_info(obj, oname, formatter, info, detail_level)
691 698 if info:
692 699 page.page(info)
693 700
694 701 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
695 702 """DEPRECATED. Compute a dict with detailed information about an object.
696 703 """
697 704 if formatter is not None:
698 705 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
699 706 'is deprecated as of IPython 5.0 and will have no effects.',
700 707 DeprecationWarning, stacklevel=2)
701 708 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
702 709
703 710 def _info(self, obj, oname='', info=None, detail_level=0):
704 711 """Compute a dict with detailed information about an object.
705 712
706 713 Optional arguments:
707 714
708 715 - oname: name of the variable pointing to the object.
709 716
710 717 - info: a structure with some information fields which may have been
711 718 precomputed already.
712 719
713 720 - detail_level: if set to 1, more information is given.
714 721 """
715 722
716 723 obj_type = type(obj)
717 724
718 725 if info is None:
719 726 ismagic = 0
720 727 isalias = 0
721 728 ospace = ''
722 729 else:
723 730 ismagic = info.ismagic
724 731 isalias = info.isalias
725 732 ospace = info.namespace
726 733
727 734 # Get docstring, special-casing aliases:
728 735 if isalias:
729 736 if not callable(obj):
730 737 try:
731 738 ds = "Alias to the system command:\n %s" % obj[1]
732 739 except:
733 740 ds = "Alias: " + str(obj)
734 741 else:
735 742 ds = "Alias to " + str(obj)
736 743 if obj.__doc__:
737 744 ds += "\nDocstring:\n" + obj.__doc__
738 745 else:
739 746 ds = getdoc(obj)
740 747 if ds is None:
741 748 ds = '<no docstring>'
742 749
743 750 # store output in a dict, we initialize it here and fill it as we go
744 751 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
745 752
746 753 string_max = 200 # max size of strings to show (snipped if longer)
747 754 shalf = int((string_max - 5) / 2)
748 755
749 756 if ismagic:
750 757 obj_type_name = 'Magic function'
751 758 elif isalias:
752 759 obj_type_name = 'System alias'
753 760 else:
754 761 obj_type_name = obj_type.__name__
755 762 out['type_name'] = obj_type_name
756 763
757 764 try:
758 765 bclass = obj.__class__
759 766 out['base_class'] = str(bclass)
760 767 except: pass
761 768
762 769 # String form, but snip if too long in ? form (full in ??)
763 770 if detail_level >= self.str_detail_level:
764 771 try:
765 772 ostr = str(obj)
766 773 str_head = 'string_form'
767 774 if not detail_level and len(ostr)>string_max:
768 775 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
769 776 ostr = ("\n" + " " * len(str_head.expandtabs())).\
770 777 join(q.strip() for q in ostr.split("\n"))
771 778 out[str_head] = ostr
772 779 except:
773 780 pass
774 781
775 782 if ospace:
776 783 out['namespace'] = ospace
777 784
778 785 # Length (for strings and lists)
779 786 try:
780 787 out['length'] = str(len(obj))
781 788 except: pass
782 789
783 790 # Filename where object was defined
784 791 binary_file = False
785 792 fname = find_file(obj)
786 793 if fname is None:
787 794 # if anything goes wrong, we don't want to show source, so it's as
788 795 # if the file was binary
789 796 binary_file = True
790 797 else:
791 798 if fname.endswith(('.so', '.dll', '.pyd')):
792 799 binary_file = True
793 800 elif fname.endswith('<string>'):
794 801 fname = 'Dynamically generated function. No source code available.'
795 802 out['file'] = compress_user(fname)
796 803
797 804 # Original source code for a callable, class or property.
798 805 if detail_level:
799 806 # Flush the source cache because inspect can return out-of-date
800 807 # source
801 808 linecache.checkcache()
802 809 try:
803 810 if isinstance(obj, property) or not binary_file:
804 811 src = getsource(obj, oname)
805 812 if src is not None:
806 813 src = src.rstrip()
807 814 out['source'] = src
808 815
809 816 except Exception:
810 817 pass
811 818
812 819 # Add docstring only if no source is to be shown (avoid repetitions).
813 820 if ds and out.get('source', None) is None:
814 821 out['docstring'] = ds
815 822
816 823 # Constructor docstring for classes
817 824 if inspect.isclass(obj):
818 825 out['isclass'] = True
819 826
820 827 # get the init signature:
821 828 try:
822 829 init_def = self._getdef(obj, oname)
823 830 except AttributeError:
824 831 init_def = None
825 832
826 833 if init_def:
827 834 out['init_definition'] = self.format(init_def)
828 835
829 836 # get the __init__ docstring
830 837 try:
831 838 obj_init = obj.__init__
832 839 except AttributeError:
833 840 init_ds = None
834 841 else:
835 842 init_ds = getdoc(obj_init)
836 843 # Skip Python's auto-generated docstrings
837 844 if init_ds == _object_init_docstring:
838 845 init_ds = None
839 846
840 847 if init_ds:
841 848 out['init_docstring'] = init_ds
842 849
843 850 # and class docstring for instances:
844 851 else:
845 852 # reconstruct the function definition and print it:
846 853 defln = self._getdef(obj, oname)
847 854 if defln:
848 855 out['definition'] = defln
849 856
850 857 # First, check whether the instance docstring is identical to the
851 858 # class one, and print it separately if they don't coincide. In
852 859 # most cases they will, but it's nice to print all the info for
853 860 # objects which use instance-customized docstrings.
854 861 if ds:
855 862 try:
856 863 cls = getattr(obj,'__class__')
857 864 except:
858 865 class_ds = None
859 866 else:
860 867 class_ds = getdoc(cls)
861 868 # Skip Python's auto-generated docstrings
862 869 if class_ds in _builtin_type_docstrings:
863 870 class_ds = None
864 871 if class_ds and ds != class_ds:
865 872 out['class_docstring'] = class_ds
866 873
867 874 # Next, try to show constructor docstrings
868 875 try:
869 876 init_ds = getdoc(obj.__init__)
870 877 # Skip Python's auto-generated docstrings
871 878 if init_ds == _object_init_docstring:
872 879 init_ds = None
873 880 except AttributeError:
874 881 init_ds = None
875 882 if init_ds:
876 883 out['init_docstring'] = init_ds
877 884
878 885 # Call form docstring for callable instances
879 886 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
880 887 call_def = self._getdef(obj.__call__, oname)
881 888 if call_def and (call_def != out.get('definition')):
882 889 # it may never be the case that call def and definition differ,
883 890 # but don't include the same signature twice
884 891 out['call_def'] = call_def
885 892 call_ds = getdoc(obj.__call__)
886 893 # Skip Python's auto-generated docstrings
887 894 if call_ds == _func_call_docstring:
888 895 call_ds = None
889 896 if call_ds:
890 897 out['call_docstring'] = call_ds
891 898
892 899 # Compute the object's argspec as a callable. The key is to decide
893 900 # whether to pull it from the object itself, from its __init__ or
894 901 # from its __call__ method.
895 902
896 903 if inspect.isclass(obj):
897 904 # Old-style classes need not have an __init__
898 905 callable_obj = getattr(obj, "__init__", None)
899 906 elif callable(obj):
900 907 callable_obj = obj
901 908 else:
902 909 callable_obj = None
903 910
904 911 if callable_obj is not None:
905 912 try:
906 913 argspec = getargspec(callable_obj)
907 914 except (TypeError, AttributeError):
908 915 # For extensions/builtins we can't retrieve the argspec
909 916 pass
910 917 else:
911 918 # named tuples' _asdict() method returns an OrderedDict, but we
912 919 # we want a normal
913 920 out['argspec'] = argspec_dict = dict(argspec._asdict())
914 921 # We called this varkw before argspec became a named tuple.
915 922 # With getfullargspec it's also called varkw.
916 923 if 'varkw' not in argspec_dict:
917 924 argspec_dict['varkw'] = argspec_dict.pop('keywords')
918 925
919 926 return object_info(**out)
920 927
921 928 def psearch(self,pattern,ns_table,ns_search=[],
922 929 ignore_case=False,show_all=False):
923 930 """Search namespaces with wildcards for objects.
924 931
925 932 Arguments:
926 933
927 934 - pattern: string containing shell-like wildcards to use in namespace
928 935 searches and optionally a type specification to narrow the search to
929 936 objects of that type.
930 937
931 938 - ns_table: dict of name->namespaces for search.
932 939
933 940 Optional arguments:
934 941
935 942 - ns_search: list of namespace names to include in search.
936 943
937 944 - ignore_case(False): make the search case-insensitive.
938 945
939 946 - show_all(False): show all names, including those starting with
940 947 underscores.
941 948 """
942 949 #print 'ps pattern:<%r>' % pattern # dbg
943 950
944 951 # defaults
945 952 type_pattern = 'all'
946 953 filter = ''
947 954
948 955 cmds = pattern.split()
949 956 len_cmds = len(cmds)
950 957 if len_cmds == 1:
951 958 # Only filter pattern given
952 959 filter = cmds[0]
953 960 elif len_cmds == 2:
954 961 # Both filter and type specified
955 962 filter,type_pattern = cmds
956 963 else:
957 964 raise ValueError('invalid argument string for psearch: <%s>' %
958 965 pattern)
959 966
960 967 # filter search namespaces
961 968 for name in ns_search:
962 969 if name not in ns_table:
963 970 raise ValueError('invalid namespace <%s>. Valid names: %s' %
964 971 (name,ns_table.keys()))
965 972
966 973 #print 'type_pattern:',type_pattern # dbg
967 974 search_result, namespaces_seen = set(), set()
968 975 for ns_name in ns_search:
969 976 ns = ns_table[ns_name]
970 977 # Normally, locals and globals are the same, so we just check one.
971 978 if id(ns) in namespaces_seen:
972 979 continue
973 980 namespaces_seen.add(id(ns))
974 981 tmp_res = list_namespace(ns, type_pattern, filter,
975 982 ignore_case=ignore_case, show_all=show_all)
976 983 search_result.update(tmp_res)
977 984
978 985 page.page('\n'.join(sorted(search_result)))
General Comments 0
You need to be logged in to leave comments. Login now