def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True): """Show detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - formatter: callable (optional) A special formatter for docstrings. The formatter is a callable that takes a string as an input and returns either a formatted string or a mime type bundle in the form of a dictionary. Although the support of custom formatter returning a string instead of a mime type bundle is deprecated. - info: a structure with some information fields which may have been precomputed already. - detail_level: if set to 1, more information is given. """ info = self._get_info(obj, oname, formatter, info, detail_level) if not enable_html_pager: del info['text/html'] page.page(info)
def pycat(self, parameter_s=''): """Show a syntax-highlighted file through a pager. This magic is similar to the cat utility, but it will assume the file to be Python source and will show it with syntax highlighting. This magic command can either take a local filename, an url, an history range (see %history) or a macro as argument :: %pycat myscript.py %pycat 7-27 %pycat myMacro %pycat http://www.example.com/myscript.py """ if not parameter_s: raise UsageError('Missing filename, URL, input history range, ' 'or macro.') try : cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False) except (ValueError, IOError): print("Error: no such file, variable, URL, history range or macro") return page.page(self.shell.pycolorize(source_to_unicode(cont)))
def psearch(self,pattern,ns_table,ns_search=[], ignore_case=False,show_all=False): """Search namespaces with wildcards for objects. Arguments: - pattern: string containing shell-like wildcards to use in namespace searches and optionally a type specification to narrow the search to objects of that type. - ns_table: dict of name->namespaces for search. Optional arguments: - ns_search: list of namespace names to include in search. - ignore_case(False): make the search case-insensitive. - show_all(False): show all names, including those starting with underscores. """ #print 'ps pattern:<%r>' % pattern # dbg # defaults type_pattern = 'all' filter = '' cmds = pattern.split() len_cmds = len(cmds) if len_cmds == 1: # Only filter pattern given filter = cmds[0] elif len_cmds == 2: # Both filter and type specified filter,type_pattern = cmds else: raise ValueError('invalid argument string for psearch: <%s>' % pattern) # filter search namespaces for name in ns_search: if name not in ns_table: raise ValueError('invalid namespace <%s>. Valid names: %s' % (name,ns_table.keys())) #print 'type_pattern:',type_pattern # dbg search_result, namespaces_seen = set(), set() for ns_name in ns_search: ns = ns_table[ns_name] # Normally, locals and globals are the same, so we just check one. if id(ns) in namespaces_seen: continue namespaces_seen.add(id(ns)) tmp_res = list_namespace(ns, type_pattern, filter, ignore_case=ignore_case, show_all=show_all) search_result.update(tmp_res) page.page('\n'.join(sorted(search_result)))
def pdoc(self, obj, oname='', formatter=None): """Print the docstring for any object. Optional: -formatter: a function to run the docstring through for specially formatted docstrings. Examples -------- In [1]: class NoInit: ...: pass In [2]: class NoDoc: ...: def __init__(self): ...: pass In [3]: %pdoc NoDoc No documentation found for NoDoc In [4]: %pdoc NoInit No documentation found for NoInit In [5]: obj = NoInit() In [6]: %pdoc obj No documentation found for obj In [5]: obj2 = NoDoc() In [6]: %pdoc obj2 No documentation found for obj2 """ head = self.__head # For convenience lines = [] ds = getdoc(obj) if formatter: ds = formatter(ds).get('plain/text', ds) if ds: lines.append(head("Class docstring:")) lines.append(indent(ds)) if inspect.isclass(obj) and hasattr(obj, '__init__'): init_ds = getdoc(obj.__init__) if init_ds is not None: lines.append(head("Init docstring:")) lines.append(indent(init_ds)) elif hasattr(obj,'__call__'): call_ds = getdoc(obj.__call__) if call_ds: lines.append(head("Call docstring:")) lines.append(indent(call_ds)) if not lines: self.noinfo('documentation',oname) else: page.page('\n'.join(lines))
def pdoc(self, obj, oname='', formatter=None): """Print the docstring for any object. Optional: -formatter: a function to run the docstring through for specially formatted docstrings. Examples -------- In [1]: class NoInit: ...: pass In [2]: class NoDoc: ...: def __init__(self): ...: pass In [3]: %pdoc NoDoc No documentation found for NoDoc In [4]: %pdoc NoInit No documentation found for NoInit In [5]: obj = NoInit() In [6]: %pdoc obj No documentation found for obj In [5]: obj2 = NoDoc() In [6]: %pdoc obj2 No documentation found for obj2 """ head = self.__head # For convenience lines = [] ds = getdoc(obj) if formatter: ds = formatter(ds).get('plain/text', ds) if ds: lines.append(head("Class docstring:")) lines.append(indent(ds)) if inspect.isclass(obj) and hasattr(obj, '__init__'): init_ds = getdoc(obj.__init__) if init_ds is not None: lines.append(head("Init docstring:")) lines.append(indent(init_ds)) elif hasattr(obj, '__call__'): call_ds = getdoc(obj.__call__) if call_ds: lines.append(head("Call docstring:")) lines.append(indent(call_ds)) if not lines: self.noinfo('documentation', oname) else: page.page('\n'.join(lines))
def less(self, arg_s): """Show a file through the pager. Files ending in .py are syntax-highlighted.""" if not arg_s: raise UsageError('Missing filename.') if arg_s.endswith('.py'): cont = self.shell.pycolorize( openpy.read_py_file(arg_s, skip_encoding_cookie=False)) else: cont = open(arg_s).read() page.page(cont)
def psource(self, obj, oname=''): """Print the source code for an object.""" # Flush the source cache because inspect can return out-of-date source linecache.checkcache() try: src = getsource(obj, oname=oname) except Exception: src = None if src is None: self.noinfo('source', oname) else: page.page(self.format(src))
def pfile(self, obj, oname=''): """Show the whole file where an object was defined.""" lineno = find_source_lines(obj) if lineno is None: self.noinfo('file', oname) return ofile = find_file(obj) # run contents of file through pager starting at line where the object # is defined, as long as the file isn't binary and is actually on the # filesystem. if ofile.endswith(('.so', '.dll', '.pyd')): print('File %r is binary, not printing.' % ofile) elif not os.path.isfile(ofile): print('File %r does not exist, not printing.' % ofile) else: # Print only text files, not extension binaries. Note that # getsourcelines returns lineno with 1-offset and page() uses # 0-offset, so we must adjust. page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
def pfile(self, parameter_s='', namespaces=None): """Print (or run through pager) the file where an object is defined. The file opens at the line where the object definition begins. yap_ipython will honor the environment variable PAGER if set, and otherwise will do its best to print the file in a convenient form. If the given argument is not an object currently defined, yap_ipython will try to interpret it as a filename (automatically adding a .py extension if needed). You can thus use %pfile as a syntax highlighting code viewer.""" # first interpret argument as an object name out = self.shell._inspect('pfile',parameter_s, namespaces) # if not, try the input as a filename if out == 'not found': try: filename = get_py_filename(parameter_s) except IOError as msg: print(msg) return page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
def page(self, parameter_s=''): """Pretty print the object and display it through a pager. %page [options] OBJECT If no object is given, use _ (last output). Options: -r: page str(object), don't pretty-print it.""" # After a function contributed by Olivier Aubert, slightly modified. # Process options/args opts, args = self.parse_options(parameter_s, 'r') raw = 'r' in opts oname = args and args or '_' info = self.shell._ofind(oname) if info['found']: txt = (raw and str or pformat)(info['obj']) page.page(txt) else: print('Object `%s` not found' % oname)
def pfile(self, parameter_s='', namespaces=None): """Print (or run through pager) the file where an object is defined. The file opens at the line where the object definition begins. yap_ipython will honor the environment variable PAGER if set, and otherwise will do its best to print the file in a convenient form. If the given argument is not an object currently defined, yap_ipython will try to interpret it as a filename (automatically adding a .py extension if needed). You can thus use %pfile as a syntax highlighting code viewer.""" # first interpret argument as an object name out = self.shell._inspect('pfile', parameter_s, namespaces) # if not, try the input as a filename if out == 'not found': try: filename = get_py_filename(parameter_s) except IOError as msg: print(msg) return page.page( self.shell.pycolorize( read_py_file(filename, skip_encoding_cookie=False)))
def page(self, parameter_s=''): """Pretty print the object and display it through a pager. %page [options] OBJECT If no object is given, use _ (last output). Options: -r: page str(object), don't pretty-print it.""" # After a function contributed by Olivier Aubert, slightly modified. # Process options/args opts, args = self.parse_options(parameter_s, 'r') raw = 'r' in opts oname = args and args or '_' info = self.shell._ofind(oname) if info['found']: txt = (raw and str or pformat)( info['obj'] ) page.page(txt) else: print('Object `%s` not found' % oname)
def pfile(self, obj, oname=''): """Show the whole file where an object was defined.""" lineno = find_source_lines(obj) if lineno is None: self.noinfo('file', oname) return ofile = find_file(obj) # run contents of file through pager starting at line where the object # is defined, as long as the file isn't binary and is actually on the # filesystem. if ofile.endswith(('.so', '.dll', '.pyd')): print('File %r is binary, not printing.' % ofile) elif not os.path.isfile(ofile): print('File %r does not exist, not printing.' % ofile) else: # Print only text files, not extension binaries. Note that # getsourcelines returns lineno with 1-offset and page() uses # 0-offset, so we must adjust. page.page( self.format( openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
def quickref(self, arg): """ Show a quick reference sheet """ from yap_ipython.core.usage import quick_reference qr = quick_reference + self._magic_docs(brief=True) page.page(qr)
def magic(self, parameter_s=''): """Print information about the magic function system. Supported formats: -latex, -brief, -rest """ mode = '' try: mode = parameter_s.split()[0][1:] except IndexError: pass brief = (mode == 'brief') rest = (mode == 'rest') magic_docs = self._magic_docs(brief, rest) if mode == 'latex': print(self.format_latex(magic_docs)) return else: magic_docs = format_screen(magic_docs) out = [ """ yap_ipython's 'magic' functions =========================== The magic function system provides a series of functions which allow you to control the behavior of yap_ipython itself, plus a lot of system-type features. There are two kinds of magics, line-oriented and cell-oriented. Line magics are prefixed with the % character and work much like OS command-line calls: they get as an argument the rest of the line, where arguments are passed without parentheses or quotes. For example, this will time the given statement:: %timeit range(1000) Cell magics are prefixed with a double %%, and they are functions that get as an argument not only the rest of the line, but also the lines below it in a separate argument. These magics are called with two arguments: the rest of the call line and the body of the cell, consisting of the lines below the first. For example:: %%timeit x = numpy.random.randn((100, 100)) numpy.linalg.svd(x) will time the execution of the numpy svd routine, running the assignment of x as part of the setup phase, which is not timed. In a line-oriented client (the terminal or Qt console yap_ipython), starting a new input with %% will automatically enter cell mode, and yap_ipython will continue reading input until a blank line is given. In the notebook, simply type the whole cell as one entity, but keep in mind that the %% escape can only be at the very start of the cell. NOTE: If you have 'automagic' enabled (via the command line option or with the %automagic function), you don't need to type in the % explicitly for line magics; cell magics always require an explicit '%%' escape. By default, yap_ipython ships with automagic on, so you should only rarely need the % escape. Example: typing '%cd mydir' (without the quotes) changes your working directory to 'mydir', if it exists. For a list of the available magic functions, use %lsmagic. For a description of any of them, type %magic_name?, e.g. '%cd?'. Currently the magic system has the following functions:""", magic_docs, "Summary of magic functions (from %slsmagic):" % magic_escapes['line'], str(self.lsmagic()), ] page.page('\n'.join(out))
def magic(self, parameter_s=''): """Print information about the magic function system. Supported formats: -latex, -brief, -rest """ mode = '' try: mode = parameter_s.split()[0][1:] except IndexError: pass brief = (mode == 'brief') rest = (mode == 'rest') magic_docs = self._magic_docs(brief, rest) if mode == 'latex': print(self.format_latex(magic_docs)) return else: magic_docs = format_screen(magic_docs) out = [""" yap_ipython's 'magic' functions =========================== The magic function system provides a series of functions which allow you to control the behavior of yap_ipython itself, plus a lot of system-type features. There are two kinds of magics, line-oriented and cell-oriented. Line magics are prefixed with the % character and work much like OS command-line calls: they get as an argument the rest of the line, where arguments are passed without parentheses or quotes. For example, this will time the given statement:: %timeit range(1000) Cell magics are prefixed with a double %%, and they are functions that get as an argument not only the rest of the line, but also the lines below it in a separate argument. These magics are called with two arguments: the rest of the call line and the body of the cell, consisting of the lines below the first. For example:: %%timeit x = numpy.random.randn((100, 100)) numpy.linalg.svd(x) will time the execution of the numpy svd routine, running the assignment of x as part of the setup phase, which is not timed. In a line-oriented client (the terminal or Qt console yap_ipython), starting a new input with %% will automatically enter cell mode, and yap_ipython will continue reading input until a blank line is given. In the notebook, simply type the whole cell as one entity, but keep in mind that the %% escape can only be at the very start of the cell. NOTE: If you have 'automagic' enabled (via the command line option or with the %automagic function), you don't need to type in the % explicitly for line magics; cell magics always require an explicit '%%' escape. By default, yap_ipython ships with automagic on, so you should only rarely need the % escape. Example: typing '%cd mydir' (without the quotes) changes your working directory to 'mydir', if it exists. For a list of the available magic functions, use %lsmagic. For a description of any of them, type %magic_name?, e.g. '%cd?'. Currently the magic system has the following functions:""", magic_docs, "Summary of magic functions (from %slsmagic):" % magic_escapes['line'], str(self.lsmagic()), ] page.page('\n'.join(out))
def psearch(self, pattern, ns_table, ns_search=[], ignore_case=False, show_all=False): """Search namespaces with wildcards for objects. Arguments: - pattern: string containing shell-like wildcards to use in namespace searches and optionally a type specification to narrow the search to objects of that type. - ns_table: dict of name->namespaces for search. Optional arguments: - ns_search: list of namespace names to include in search. - ignore_case(False): make the search case-insensitive. - show_all(False): show all names, including those starting with underscores. """ #print 'ps pattern:<%r>' % pattern # dbg # defaults type_pattern = 'all' filter = '' cmds = pattern.split() len_cmds = len(cmds) if len_cmds == 1: # Only filter pattern given filter = cmds[0] elif len_cmds == 2: # Both filter and type specified filter, type_pattern = cmds else: raise ValueError('invalid argument string for psearch: <%s>' % pattern) # filter search namespaces for name in ns_search: if name not in ns_table: raise ValueError('invalid namespace <%s>. Valid names: %s' % (name, ns_table.keys())) #print 'type_pattern:',type_pattern # dbg search_result, namespaces_seen = set(), set() for ns_name in ns_search: ns = ns_table[ns_name] # Normally, locals and globals are the same, so we just check one. if id(ns) in namespaces_seen: continue namespaces_seen.add(id(ns)) tmp_res = list_namespace(ns, type_pattern, filter, ignore_case=ignore_case, show_all=show_all) search_result.update(tmp_res) page.page('\n'.join(sorted(search_result)))
def man(self, arg_s): """Find the man page for the given command and display in pager.""" page.page( self.shell.getoutput('man %s | col -b' % arg_s, split=False))