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