oinspect.py 34 KB

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