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