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