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