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 dictionnary. 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 handle_execute_reply(self, msg_id, timeout=None): msg = self.client.shell_channel.get_msg(block=False, timeout=timeout) if msg["parent_header"].get("msg_id", None) == msg_id: self.handle_iopub(msg_id) content = msg["content"] status = content['status'] if status == 'aborted': self.write('Aborted\n') return elif status == 'ok': # handle payloads for item in content.get("payload", []): source = item['source'] if source == 'page': page.page(item['data']['text/plain']) elif source == 'set_next_input': self.next_input = item['text'] elif source == 'ask_exit': self.keepkernel = item.get('keepkernel', False) self.ask_exit() elif status == 'error': pass self.execution_count = int(content["execution_count"] + 1)
def pfile(self,obj,oname=''): """Show the whole file where an object was defined.""" try: try: lineno = inspect.getsourcelines(obj)[1] except TypeError: # For instances, try the class object like getsource() does if hasattr(obj,'__class__'): lineno = inspect.getsourcelines(obj.__class__)[1] # Adjust the inspected object so getabsfile() below works obj = obj.__class__ except: self.noinfo('file',oname) return # We only reach this point if object was successfully queried # run contents of file through pager starting at line # where the object is defined ofile = inspect.getabsfile(obj) 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(open(ofile).read()),lineno-1)
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.""" head = self.__head # so that itpl can find it even if private ds = getdoc(obj) if formatter: ds = formatter(ds) if inspect.isclass(obj): init_ds = getdoc(obj.__init__) output = itpl('$head("Class Docstring:")\n' '$indent(ds)\n' '$head("Constructor Docstring"):\n' '$indent(init_ds)') elif isinstance(obj,object) and hasattr(obj,'__call__'): call_ds = getdoc(obj.__call__) if call_ds: output = itpl('$head("Class Docstring:")\n$indent(ds)\n' '$head("Calling Docstring:")\n$indent(call_ds)') else: output = ds else: output = ds if output is None: self.noinfo('documentation',oname) return page.page(output)
def lsdev(self, parameter_s=''): """Lists all known tango devices. Usage: lsdev [<device name filter(regular expression)] Examples: In [1]: lsdev In [2]: lsdev sys.*""" if parameter_s: reg_exp = re.compile(parameter_s, re.IGNORECASE) else: reg_exp = None db = __get_db() if db is None: print("You are not connected to any Tango Database. Device list is empty") return data = db._db_cache.devices s = io.BytesIO() lengths = 40, 25, 25, 20 title = "Device", "Alias", "Server", "Class" templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}}" msg = templ.format(*title, l=lengths) print(msg, file=s) print(*map(operator.mul, lengths, len(lengths)*"-"), file=s) for d, v in data.items(): if reg_exp and not reg_exp.match(d): continue print(templ.format(d, v[0], v[1], v[2], l=lengths), file=s) s.seek(0) page(s.read())
def handle_execute_reply(self, msg_id, timeout=None): msg = self.client.shell_channel.get_msg(block=False, timeout=timeout) if msg["parent_header"].get("msg_id", None) == msg_id: self.handle_iopub(msg_id) content = msg["content"] status = content['status'] if status == 'aborted': self.write('Aborted\n') return elif status == 'ok': # handle payloads for item in content["payload"]: source = item['source'] if source == 'page': page.page(item['data']['text/plain']) elif source == 'set_next_input': self.set_next_input(item['text']) elif status == 'error': for frame in content["traceback"]: print(frame, file=io.stderr) self.execution_count = int(content["execution_count"] + 1)
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.""" head = self.__head # For convenience ds = getdoc(obj) if formatter: ds = formatter(ds) if inspect.isclass(obj): init_ds = getdoc(obj.__init__) output = "\n".join([head("Class Docstring:"), indent(ds), head("Constructor Docstring:"), indent(init_ds)]) elif (type(obj) is types.InstanceType or isinstance(obj,object)) \ and hasattr(obj,'__call__'): call_ds = getdoc(obj.__call__) if call_ds: output = "\n".join([head("Class Docstring:"), indent(ds), head("Calling Docstring:"), indent(call_ds)]) else: output = ds else: output = ds if output is None: self.noinfo('documentation',oname) return page.page(output)
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 handle(self, line_info): """Try to get some help for the object. obj? or ?obj -> basic information. obj?? or ??obj -> more details. """ normal_handler = self.prefilter_manager.get_handler_by_name('normal') line = line_info.line # We need to make sure that we don't process lines which would be # otherwise valid python, such as "x=1 # what?" try: codeop.compile_command(line) except SyntaxError: # We should only handle as help stuff which is NOT valid syntax if line[0]==ESC_HELP: line = line[1:] elif line[-1]==ESC_HELP: line = line[:-1] self.shell.log(line, '#?'+line, line_info.continue_prompt) if line: #print 'line:<%r>' % line # dbg self.shell.magic_pinfo(line) else: page(self.shell.usage, screen_lines=self.shell.usable_screen_length) return '' # Empty string is needed here! except: raise # Pass any other exceptions through to the normal handler return normal_handler.handle(line_info) else: raise # If the code compiles ok, we should handle it normally return normal_handler.handle(line_info)
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 # This currently fails in Python 3, because it shows the constructor # docstring from object. #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) 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("Constructor Docstring:")) lines.append(indent(init_ds)) elif isinstance(obj,object) and hasattr(obj,'__call__'): call_ds = getdoc(obj.__call__) if call_ds: lines.append(head("Calling Docstring:")) lines.append(indent(call_ds)) if not lines: self.noinfo('documentation',oname) else: page.page('\n'.join(lines))
def magic_less(self, arg_s): """Show a file through the pager. Files ending in .py are syntax-highlighted.""" cont = open(arg_s).read() if arg_s.endswith('.py'): cont = self.shell.pycolorize(cont) page.page(cont)
def where(self, query): """ Show backtrace """ context = [] for f in reversed(self.frames[self.frame_offset:]): context.append(get_context(f)) page.page("".join(context))
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 pinfo(self, obj, oname="", formatter=None, info=None, detail_level=0): """Show detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - formatter: special formatter for docstrings (see pdoc) - 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.info(obj, oname=oname, formatter=formatter, info=info, detail_level=detail_level) displayfields = [] def add_fields(fields): for title, key in fields: field = info[key] if field is not None: displayfields.append((title, field.rstrip())) add_fields(self.pinfo_fields1) # Base class for old-style instances if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info["base_class"]: displayfields.append(("Base Class", info["base_class"].rstrip())) add_fields(self.pinfo_fields2) # Namespace if info["namespace"] != "Interactive": displayfields.append(("Namespace", info["namespace"].rstrip())) add_fields(self.pinfo_fields3) if info["isclass"] and info["init_definition"]: displayfields.append(("Init definition", info["init_definition"].rstrip())) # Source or docstring, depending on detail level and whether # source found. if detail_level > 0 and info["source"] is not None: displayfields.append(("Source", self.format(cast_unicode(info["source"])))) elif info["docstring"] is not None: displayfields.append(("Docstring", info["docstring"])) # Constructor info for classes if info["isclass"]: if info["init_docstring"] is not None: displayfields.append(("Init docstring", info["init_docstring"])) # Info for objects: else: add_fields(self.pinfo_fields_obj) # Finally send to printer/pager: if displayfields: page.page(self._format_fields(displayfields))
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 pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0): if isinstance(obj, session_module.PluginRunner): # Delegate info generation for PluginRunners. result = self.plugin_pinfo(obj, detail_level=detail_level) if result: page.page(result) else: oinspect.Inspector.pinfo( self, obj, oname=oname, formatter=formatter, info=info, detail_level=detail_level)
def gphelp(): """Print information about the Gnuplot facilities in IPython.""" page(""" IPython provides an interface to access the Gnuplot scientific plotting system, in an environment similar to that of Mathematica or Matlab. New top-level global objects ---------------------------- Please see their respective docstrings for further details. - gp: a running Gnuplot instance. You can access its methods as gp.<method>. gp(`a string`) will execute the given string as if it had been typed in an interactive gnuplot window. - plot, splot, replot and hardcopy: aliases to the methods of the same name in the global running Gnuplot instance gp. These allow you to simply type: In [1]: plot(x,sin(x),title='Sin(x)') # assuming x is a Numeric array and obtain a plot of sin(x) vs x with the title 'Sin(x)'. - gp_new: a function which returns a new Gnuplot instance. This can be used to have multiple Gnuplot instances running in your session to compare different plots, each in a separate window. - Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its functions with improved versions (Gnuplot2 comes with IPython). - gpdata, gpfile, gpstring, gpfunc, gpgrid: aliases to Gnuplot.Data, Gnuplot.File, Gnuplot.String, Gnuplot.Func and Gnuplot.GridData respectively. These functions create objects which can then be passed to the plotting commands. See the Gnuplot.py documentation for details. Keep in mind that all commands passed to a Gnuplot instance are executed in the Gnuplot namespace, where no Python variables exist. For example, for plotting sin(x) vs x as above, typing In [2]: gp('plot x,sin(x)') would not work. Instead, you would get the plot of BOTH the functions 'x' and 'sin(x)', since Gnuplot doesn't know about the 'x' Python array. The plot() method lives in python and does know about these variables. New magic functions ------------------- %gpc: pass one command to Gnuplot and execute it or open a Gnuplot shell where each line of input is executed. %gp_set_default: reset the value of IPython's global Gnuplot instance.""")
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) except: self.noinfo('source',oname) else: page.page(self.format(src))
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.') cont = open(arg_s).read() if arg_s.endswith('.py'): cont = self.shell.pycolorize(cont) page.page(cont)
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 pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0): """Show detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - formatter: special formatter for docstrings (see pdoc) - 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.info(obj, oname=oname, formatter=formatter, info=info, detail_level=detail_level) displayfields = [] for title, key in self.pinfo_fields1: field = info[key] if field is not None: displayfields.append((title, field.rstrip())) # Source or docstring, depending on detail level and whether # source found. if detail_level > 0 and info['source'] is not None: displayfields.append(("Source", info['source'])) elif info['docstring'] is not None: displayfields.append(("Docstring", info["docstring"])) # Constructor info for classes if info['isclass']: if info['init_definition'] or info['init_docstring']: displayfields.append(("Constructor information", "")) if info['init_definition'] is not None: displayfields.append((" Definition", info['init_definition'].rstrip())) if info['init_docstring'] is not None: displayfields.append((" Docstring", indent(info['init_docstring']))) # Info for objects: else: for title, key in self.pinfo_fields_obj: field = info[key] if field is not None: displayfields.append((title, field.rstrip())) # Finally send to printer/pager: if displayfields: page.page(self._format_fields(displayfields))
def doc(elt): "Show `show_doc` info in preview window along with link to full docs." global use_relative_links use_relative_links = False elt = getattr(elt, '__func__', elt) md = show_doc(elt, markdown=False) if is_fastai_class(elt): md += f'\n\n<a href="{get_fn_link(elt)}" target="_blank" rel="noreferrer noopener">Show in docs</a>' output = md2html(md) use_relative_links = True if IS_IN_COLAB: get_ipython().run_cell_magic(u'html', u'', output) else: try: page.page({'text/html': output}) except: display(Markdown(md))
def showsource(self, query): """ Show source of object """ obj = self.active_frame.locals.get( query, self.active_frame.globals.get(query, None)) if obj is None: return "Not found: %s" % query try: s = inspect.getsource(obj) except TypeError as f: print("%s" % f, file=sys.stderr) return if has_pygments: s = "\n".join(highlight(s.split("\n"))) page.page(s)
def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0): """Show detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - formatter: special formatter for docstrings (see pdoc) - info: a structure with some information fields which may have been precomputed already. - detail_level: if set to 1, more information is given. """ text = self._format_info(obj, oname, formatter, info, detail_level) if text: page.page(text)
def ls(self, query): """ Show local variables/methods/class properties """ lines = [] width = terminal_size()[0] methods = [] properties = [] has_query = True that = self.shell.user_ns.get(query, None) if that is None: that = self.active_frame.locals.get("self", []) has_query = False # apparently there is no better way to check if the caller # is a method for attr in dir(that): try: value = getattr(that, attr) except Exception: continue if isinstance(value, types.MethodType): methods.append(attr) else: properties.append(attr) if len(methods) > 0: lines.append("local methods:") lines.extend(self.build_terminal_list(methods, width)) if len(properties) > 0: lines.append("properties") props = self.build_terminal_list(properties, width) lines.extend(props) if not has_query: lines.append("local variables:") local_vars = self.build_terminal_list( self.active_frame.locals.keys(), width) lines.extend(local_vars) page.page("\n".join(lines))
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. """ try: filename = get_py_filename(parameter_s) cont = file_read(filename) except IOError: try: cont = eval(parameter_s, self.shell.user_ns) except NameError: cont = None if cont is None: print "Error: no such file or variable" return page.page(self.shell.pycolorize(cont))
def params(self, parameter_s='', namespaces=None): """ The %params line magic accepts a single argument which is a handle on the parameterized object to be inspected. If the object can be found in the active namespace, information about the object's parameters is displayed in the IPython pager. Usage: %params <parameterized class or object> """ if parameter_s=='': print("Please specify an object to inspect.") return # Beware! Uses IPython internals that may change in future... obj = self.shell._object_find(parameter_s) if obj.found is False: print("Object %r not found in the namespace." % parameter_s) return page.page(self.param_pager(obj.obj))
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=""): """Print (or run through pager) the file where an object is defined. The file opens at the line where the object definition begins. 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, 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) # 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.inspector.format(open(filename).read()))
def prun(self, parameter_s='', cell=None, user_mode=True, opts=None,arg_lst=None,prog_ns=None): """Run a statement through the python code profiler. Usage, in line mode: %prun [options] statement Usage, in cell mode: %%prun [options] [statement] code... code... In cell mode, the additional code lines are appended to the (possibly empty) statement in the first line. Cell mode allows you to easily profile multiline blocks without having to put them in a separate function. The given statement (which doesn't require quote marks) is run via the python profiler in a manner similar to the profile.run() function. Namespaces are internally managed to work correctly; profile.run cannot be used in IPython because it makes certain assumptions about namespaces which do not hold under IPython. Options: -l <limit>: you can place restrictions on what or how much of the profile gets printed. The limit value can be: * A string: only information for function names containing this string is printed. * An integer: only these many lines are printed. * A float (between 0 and 1): this fraction of the report is printed (for example, use a limit of 0.4 to see the topmost 40% only). You can combine several limits with repeated use of the option. For example, '-l __init__ -l 5' will print only the topmost 5 lines of information about class constructors. -r: return the pstats.Stats object generated by the profiling. This object has all the information about the profile in it, and you can later use it for further analysis or in other functions. -s <key>: sort profile by given key. You can provide more than one key by using the option several times: '-s key1 -s key2 -s key3...'. The default sorting key is 'time'. The following is copied verbatim from the profile documentation referenced below: When more than one key is provided, additional keys are used as secondary criteria when the there is equality in all keys selected before them. Abbreviations can be used for any key names, as long as the abbreviation is unambiguous. The following are the keys currently defined: Valid Arg Meaning "calls" call count "cumulative" cumulative time "file" file name "module" file name "pcalls" primitive call count "line" line number "name" function name "nfl" name/file/line "stdname" standard name "time" internal time Note that all sorts on statistics are in descending order (placing most time consuming items first), where as name, file, and line number searches are in ascending order (i.e., alphabetical). The subtle distinction between "nfl" and "stdname" is that the standard name is a sort of the name as printed, which means that the embedded line numbers get compared in an odd way. For example, lines 3, 20, and 40 would (if the file names were the same) appear in the string order "20" "3" and "40". In contrast, "nfl" does a numeric compare of the line numbers. In fact, sort_stats("nfl") is the same as sort_stats("name", "file", "line"). -T <filename>: save profile results as shown on screen to a text file. The profile is still shown on screen. -D <filename>: save (via dump_stats) profile statistics to given filename. This data is in a format understood by the pstats module, and is generated by a call to the dump_stats() method of profile objects. The profile is still shown on screen. -q: suppress output to the pager. Best used with -T and/or -D above. If you want to run complete programs under the profiler's control, use '%run -p [prof_opts] filename.py [args to program]' where prof_opts contains profiler specific options as described here. You can read the complete documentation for the profile module with:: In [1]: import profile; profile.help() """ opts_def = Struct(D=[''],l=[],s=['time'],T=['']) if user_mode: # regular user call opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q', list_all=True, posix=False) namespace = self.shell.user_ns if cell is not None: arg_str += '\n' + cell else: # called to run a program by %run -p try: filename = get_py_filename(arg_lst[0]) except IOError as e: try: msg = str(e) except UnicodeError: msg = e.message error(msg) return arg_str = 'execfile(filename,prog_ns)' namespace = { 'execfile': self.shell.safe_execfile, 'prog_ns': prog_ns, 'filename': filename } opts.merge(opts_def) prof = profile.Profile() try: prof = prof.runctx(arg_str,namespace,namespace) sys_exit = '' except SystemExit: sys_exit = """*** SystemExit exception caught in code being profiled.""" stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s) lims = opts.l if lims: lims = [] # rebuild lims with ints/floats/strings for lim in opts.l: try: lims.append(int(lim)) except ValueError: try: lims.append(float(lim)) except ValueError: lims.append(lim) # Trap output. stdout_trap = StringIO() if hasattr(stats,'stream'): # In newer versions of python, the stats object has a 'stream' # attribute to write into. stats.stream = stdout_trap stats.print_stats(*lims) else: # For older versions, we manually redirect stdout during printing sys_stdout = sys.stdout try: sys.stdout = stdout_trap stats.print_stats(*lims) finally: sys.stdout = sys_stdout output = stdout_trap.getvalue() output = output.rstrip() if 'q' not in opts: page.page(output) print sys_exit, dump_file = opts.D[0] text_file = opts.T[0] if dump_file: dump_file = unquote_filename(dump_file) prof.dump_stats(dump_file) print '\n*** Profile stats marshalled to file',\ `dump_file`+'.',sys_exit if text_file: text_file = unquote_filename(text_file) pfile = open(text_file,'w') pfile.write(output) pfile.close() print '\n*** Profile printout saved to text file',\ `text_file`+'.',sys_exit if opts.has_key('r'): return stats else: return None
def page_guiref(arg_s=None): """Show a basic reference about the GUI Console.""" from IPython.core import page page.page(gui_reference, auto_html=True)
def info(cls, obj): disabled = Store.output_settings._disable_info_output if Store.output_settings.options['info'] and not disabled: page.page(InfoPrinter.info(obj, ansi=True))
def magic_guiref(self, arg_s): """Show a basic reference about the GUI console.""" from IPython.core.usage import gui_reference page.page(gui_reference, auto_html=True)
class OSMagics(Magics): """Magics to interact with the underlying OS (shell-type functionality). """ @skip_doctest @line_magic def alias(self, parameter_s=''): """Define an alias for a system command. '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd' Then, typing 'alias_name params' will execute the system command 'cmd params' (from your underlying operating system). Aliases have lower precedence than magic functions and Python normal variables, so if 'foo' is both a Python variable and an alias, the alias can not be executed until 'del foo' removes the Python variable. You can use the %l specifier in an alias definition to represent the whole line when the alias is called. For example:: In [2]: alias bracket echo "Input in brackets: <%l>" In [3]: bracket hello world Input in brackets: <hello world> You can also define aliases with parameters using %s specifiers (one per parameter):: In [1]: alias parts echo first %s second %s In [2]: %parts A B first A second B In [3]: %parts A Incorrect number of arguments: 2 expected. parts is an alias to: 'echo first %s second %s' Note that %l and %s are mutually exclusive. You can only use one or the other in your aliases. Aliases expand Python variables just like system calls using ! or !! do: all expressions prefixed with '$' get expanded. For details of the semantic rules, see PEP-215: http://www.python.org/peps/pep-0215.html. This is the library used by IPython for variable expansion. If you want to access a true shell variable, an extra $ is necessary to prevent its expansion by IPython:: In [6]: alias show echo In [7]: PATH='A Python string' In [8]: show $PATH A Python string In [9]: show $$PATH /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:... You can use the alias facility to acess all of $PATH. See the %rehash and %rehashx functions, which automatically create aliases for the contents of your $PATH. If called with no parameters, %alias prints the current alias table.""" par = parameter_s.strip() if not par: aliases = sorted(self.shell.alias_manager.aliases) # stored = self.shell.db.get('stored_aliases', {} ) # for k, v in stored: # atab.append(k, v[0]) print "Total number of aliases:", len(aliases) sys.stdout.flush() return aliases # Now try to define a new one try: alias, cmd = par.split(None, 1) except: print oinspect.getdoc(self.alias) else: self.shell.alias_manager.soft_define_alias(alias, cmd) # end magic_alias @line_magic def unalias(self, parameter_s=''): """Remove an alias""" aname = parameter_s.strip() self.shell.alias_manager.undefine_alias(aname) stored = self.shell.db.get('stored_aliases', {}) if aname in stored: print "Removing %stored alias", aname del stored[aname] self.shell.db['stored_aliases'] = stored @line_magic def rehashx(self, parameter_s=''): """Update the alias table with all executable files in $PATH. This version explicitly checks that every entry in $PATH is a file with execute access (os.X_OK), so it is much slower than %rehash. Under Windows, it checks executability as a match against a '|'-separated string of extensions, stored in the IPython config variable win_exec_ext. This defaults to 'exe|com|bat'. This function also resets the root module cache of module completer, used on slow filesystems. """ from IPython.core.alias import InvalidAliasError # for the benefit of module completer in ipy_completers.py del self.shell.db['rootmodules'] path = [ os.path.abspath(os.path.expanduser(p)) for p in os.environ.get('PATH', '').split(os.pathsep) ] path = filter(os.path.isdir, path) syscmdlist = [] # Now define isexec in a cross platform manner. if os.name == 'posix': isexec = lambda fname:os.path.isfile(fname) and \ os.access(fname,os.X_OK) else: try: winext = os.environ['pathext'].replace(';', '|').replace('.', '') except KeyError: winext = 'exe|com|bat|py' if 'py' not in winext: winext += '|py' execre = re.compile(r'(.*)\.(%s)$' % winext, re.IGNORECASE) isexec = lambda fname: os.path.isfile(fname) and execre.match(fname ) savedir = os.getcwdu() # Now walk the paths looking for executables to alias. try: # write the whole loop for posix/Windows so we don't have an if in # the innermost part if os.name == 'posix': for pdir in path: os.chdir(pdir) for ff in os.listdir(pdir): if isexec(ff): try: # Removes dots from the name since ipython # will assume names with dots to be python. self.shell.alias_manager.define_alias( ff.replace('.', ''), ff) except InvalidAliasError: pass else: syscmdlist.append(ff) else: no_alias = self.shell.alias_manager.no_alias for pdir in path: os.chdir(pdir) for ff in os.listdir(pdir): base, ext = os.path.splitext(ff) if isexec(ff) and base.lower() not in no_alias: if ext.lower() == '.exe': ff = base try: # Removes dots from the name since ipython # will assume names with dots to be python. self.shell.alias_manager.define_alias( base.lower().replace('.', ''), ff) except InvalidAliasError: pass syscmdlist.append(ff) self.shell.db['syscmdlist'] = syscmdlist finally: os.chdir(savedir) @skip_doctest @line_magic def pwd(self, parameter_s=''): """Return the current working directory path. Examples -------- :: In [9]: pwd Out[9]: '/home/tsuser/sprint/ipython' """ return os.getcwdu() @skip_doctest @line_magic def cd(self, parameter_s=''): """Change the current working directory. This command automatically maintains an internal list of directories you visit during your IPython session, in the variable _dh. The command %dhist shows this history nicely formatted. You can also do 'cd -<tab>' to see directory history conveniently. Usage: cd 'dir': changes to directory 'dir'. cd -: changes to the last visited directory. cd -<n>: changes to the n-th directory in the directory history. cd --foo: change to directory that matches 'foo' in history cd -b <bookmark_name>: jump to a bookmark set by %bookmark (note: cd <bookmark_name> is enough if there is no directory <bookmark_name>, but a bookmark with the name exists.) 'cd -b <tab>' allows you to tab-complete bookmark names. Options: -q: quiet. Do not print the working directory after the cd command is executed. By default IPython's cd command does print this directory, since the default prompts do not display path information. Note that !cd doesn't work for this purpose because the shell where !command runs is immediately discarded after executing 'command'. Examples -------- :: In [10]: cd parent/child /home/tsuser/parent/child """ oldcwd = os.getcwdu() numcd = re.match(r'(-)(\d+)$', parameter_s) # jump in directory history by number if numcd: nn = int(numcd.group(2)) try: ps = self.shell.user_ns['_dh'][nn] except IndexError: print 'The requested directory does not exist in history.' return else: opts = {} elif parameter_s.startswith('--'): ps = None fallback = None pat = parameter_s[2:] dh = self.shell.user_ns['_dh'] # first search only by basename (last component) for ent in reversed(dh): if pat in os.path.basename(ent) and os.path.isdir(ent): ps = ent break if fallback is None and pat in ent and os.path.isdir(ent): fallback = ent # if we have no last part match, pick the first full path match if ps is None: ps = fallback if ps is None: print "No matching entry in directory history" return else: opts = {} else: #turn all non-space-escaping backslashes to slashes, # for c:\windows\directory\names\ parameter_s = re.sub(r'\\(?! )', '/', parameter_s) opts, ps = self.parse_options(parameter_s, 'qb', mode='string') # jump to previous if ps == '-': try: ps = self.shell.user_ns['_dh'][-2] except IndexError: raise UsageError('%cd -: No previous directory to change to.') # jump to bookmark if needed else: if not os.path.isdir(ps) or 'b' in opts: bkms = self.shell.db.get('bookmarks', {}) if ps in bkms: target = bkms[ps] print '(bookmark:%s) -> %s' % (ps, target) ps = target else: if 'b' in opts: raise UsageError( "Bookmark '%s' not found. " "Use '%%bookmark -l' to see your bookmarks." % ps) # strip extra quotes on Windows, because os.chdir doesn't like them ps = unquote_filename(ps) # at this point ps should point to the target dir if ps: try: os.chdir(os.path.expanduser(ps)) if hasattr(self.shell, 'term_title') and self.shell.term_title: set_term_title('IPython: ' + abbrev_cwd()) except OSError: print sys.exc_info()[1] else: cwd = os.getcwdu() dhist = self.shell.user_ns['_dh'] if oldcwd != cwd: dhist.append(cwd) self.shell.db['dhist'] = compress_dhist(dhist)[-100:] else: os.chdir(self.shell.home_dir) if hasattr(self.shell, 'term_title') and self.shell.term_title: set_term_title('IPython: ' + '~') cwd = os.getcwdu() dhist = self.shell.user_ns['_dh'] if oldcwd != cwd: dhist.append(cwd) self.shell.db['dhist'] = compress_dhist(dhist)[-100:] if not 'q' in opts and self.shell.user_ns['_dh']: print self.shell.user_ns['_dh'][-1] @line_magic def env(self, parameter_s=''): """List environment variables.""" return dict(os.environ) @line_magic def pushd(self, parameter_s=''): """Place the current dir on stack and change directory. Usage:\\ %pushd ['dirname'] """ dir_s = self.shell.dir_stack tgt = os.path.expanduser(unquote_filename(parameter_s)) cwd = os.getcwdu().replace(self.shell.home_dir, '~') if tgt: self.cd(parameter_s) dir_s.insert(0, cwd) return self.shell.magic('dirs') @line_magic def popd(self, parameter_s=''): """Change to directory popped off the top of the stack. """ if not self.shell.dir_stack: raise UsageError("%popd on empty stack") top = self.shell.dir_stack.pop(0) self.cd(top) print "popd ->", top @line_magic def dirs(self, parameter_s=''): """Return the current directory stack.""" return self.shell.dir_stack @line_magic def dhist(self, parameter_s=''): """Print your history of visited directories. %dhist -> print full history\\ %dhist n -> print last n entries only\\ %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\ This history is automatically maintained by the %cd command, and always available as the global list variable _dh. You can use %cd -<n> to go to directory number <n>. Note that most of time, you should view directory history by entering cd -<TAB>. """ dh = self.shell.user_ns['_dh'] if parameter_s: try: args = map(int, parameter_s.split()) except: self.arg_err(self.dhist) return if len(args) == 1: ini, fin = max(len(dh) - (args[0]), 0), len(dh) elif len(args) == 2: ini, fin = args else: self.arg_err(self.dhist) return else: ini, fin = 0, len(dh) nlprint(dh, header='Directory history (kept in _dh)', start=ini, stop=fin) @skip_doctest @line_magic def sc(self, parameter_s=''): """Shell capture - run shell command and capture output (DEPRECATED use !). DEPRECATED. Suboptimal, retained for backwards compatibility. You should use the form 'var = !command' instead. Example: "%sc -l myfiles = ls ~" should now be written as "myfiles = !ls ~" myfiles.s, myfiles.l and myfiles.n still apply as documented below. -- %sc [options] varname=command IPython will run the given command using commands.getoutput(), and will then update the user's interactive namespace with a variable called varname, containing the value of the call. Your command can contain shell wildcards, pipes, etc. The '=' sign in the syntax is mandatory, and the variable name you supply must follow Python's standard conventions for valid names. (A special format without variable name exists for internal use) Options: -l: list output. Split the output on newlines into a list before assigning it to the given variable. By default the output is stored as a single string. -v: verbose. Print the contents of the variable. In most cases you should not need to split as a list, because the returned value is a special type of string which can automatically provide its contents either as a list (split on newlines) or as a space-separated string. These are convenient, respectively, either for sequential processing or to be passed to a shell command. For example:: # Capture into variable a In [1]: sc a=ls *py # a is a string with embedded newlines In [2]: a Out[2]: 'setup.py\\nwin32_manual_post_install.py' # which can be seen as a list: In [3]: a.l Out[3]: ['setup.py', 'win32_manual_post_install.py'] # or as a whitespace-separated string: In [4]: a.s Out[4]: 'setup.py win32_manual_post_install.py' # a.s is useful to pass as a single command line: In [5]: !wc -l $a.s 146 setup.py 130 win32_manual_post_install.py 276 total # while the list form is useful to loop over: In [6]: for f in a.l: ...: !wc -l $f ...: 146 setup.py 130 win32_manual_post_install.py Similarly, the lists returned by the -l option are also special, in the sense that you can equally invoke the .s attribute on them to automatically get a whitespace-separated string from their contents:: In [7]: sc -l b=ls *py In [8]: b Out[8]: ['setup.py', 'win32_manual_post_install.py'] In [9]: b.s Out[9]: 'setup.py win32_manual_post_install.py' In summary, both the lists and strings used for output capture have the following special attributes:: .l (or .list) : value as list. .n (or .nlstr): value as newline-separated string. .s (or .spstr): value as space-separated string. """ opts, args = self.parse_options(parameter_s, 'lv') # Try to get a variable name and command to run try: # the variable name must be obtained from the parse_options # output, which uses shlex.split to strip options out. var, _ = args.split('=', 1) var = var.strip() # But the command has to be extracted from the original input # parameter_s, not on what parse_options returns, to avoid the # quote stripping which shlex.split performs on it. _, cmd = parameter_s.split('=', 1) except ValueError: var, cmd = '', '' # If all looks ok, proceed split = 'l' in opts out = self.shell.getoutput(cmd, split=split) if 'v' in opts: print '%s ==\n%s' % (var, pformat(out)) if var: self.shell.user_ns.update({var: out}) else: return out @line_cell_magic def sx(self, line='', cell=None): """Shell execute - run shell command and capture output (!! is short-hand). %sx command IPython will run the given command using commands.getoutput(), and return the result formatted as a list (split on '\\n'). Since the output is _returned_, it will be stored in ipython's regular output cache Out[N] and in the '_N' automatic variables. Notes: 1) If an input line begins with '!!', then %sx is automatically invoked. That is, while:: !ls causes ipython to simply issue system('ls'), typing:: !!ls is a shorthand equivalent to:: %sx ls 2) %sx differs from %sc in that %sx automatically splits into a list, like '%sc -l'. The reason for this is to make it as easy as possible to process line-oriented shell output via further python commands. %sc is meant to provide much finer control, but requires more typing. 3) Just like %sc -l, this is a list with special attributes: :: .l (or .list) : value as list. .n (or .nlstr): value as newline-separated string. .s (or .spstr): value as whitespace-separated string. This is very useful when trying to use such lists as arguments to system commands.""" if cell is None: # line magic return self.shell.getoutput(line) else: opts, args = self.parse_options(line, '', 'out=') output = self.shell.getoutput(cell) out_name = opts.get('out', opts.get('o')) if out_name: self.shell.user_ns[out_name] = output else: return output system = line_cell_magic('system')(sx) bang = cell_magic('!')(sx) @line_magic def bookmark(self, parameter_s=''): """Manage IPython's bookmark system. %bookmark <name> - set bookmark to current dir %bookmark <name> <dir> - set bookmark to <dir> %bookmark -l - list all bookmarks %bookmark -d <name> - remove bookmark %bookmark -r - remove all bookmarks You can later on access a bookmarked folder with:: %cd -b <name> or simply '%cd <name>' if there is no directory called <name> AND there is such a bookmark defined. Your bookmarks persist through IPython sessions, but they are associated with each profile.""" opts, args = self.parse_options(parameter_s, 'drl', mode='list') if len(args) > 2: raise UsageError("%bookmark: too many arguments") bkms = self.shell.db.get('bookmarks', {}) if 'd' in opts: try: todel = args[0] except IndexError: raise UsageError( "%bookmark -d: must provide a bookmark to delete") else: try: del bkms[todel] except KeyError: raise UsageError( "%%bookmark -d: Can't delete bookmark '%s'" % todel) elif 'r' in opts: bkms = {} elif 'l' in opts: bks = bkms.keys() bks.sort() if bks: size = max(map(len, bks)) else: size = 0 fmt = '%-' + str(size) + 's -> %s' print 'Current bookmarks:' for bk in bks: print fmt % (bk, bkms[bk]) else: if not args: raise UsageError( "%bookmark: You must specify the bookmark name") elif len(args) == 1: bkms[args[0]] = os.getcwdu() elif len(args) == 2: bkms[args[0]] = args[1] self.shell.db['bookmarks'] = bkms @line_magic 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 """ try: cont = self.shell.find_user_code(parameter_s) except ValueError, IOError: print "Error: no such file, variable, URL, history range or macro" return page.page(self.shell.pycolorize(cont))
def _run_with_profiler(self, code, opts, namespace): """ Run `code` with profiler. Used by ``%prun`` and ``%run -p``. Parameters ---------- code : str Code to be executed. opts : Struct Options parsed by `self.parse_options`. namespace : dict A dictionary for Python namespace (e.g., `self.shell.user_ns`). """ # Fill default values for unspecified options: opts.merge(Struct(D=[''], l=[], s=['time'], T=[''])) prof = profile.Profile() try: prof = prof.runctx(code, namespace, namespace) sys_exit = '' except SystemExit: sys_exit = """*** SystemExit exception caught in code being profiled.""" stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s) lims = opts.l if lims: lims = [] # rebuild lims with ints/floats/strings for lim in opts.l: try: lims.append(int(lim)) except ValueError: try: lims.append(float(lim)) except ValueError: lims.append(lim) # Trap output. stdout_trap = StringIO() stats_stream = stats.stream try: stats.stream = stdout_trap stats.print_stats(*lims) finally: stats.stream = stats_stream output = stdout_trap.getvalue() output = output.rstrip() if 'q' not in opts: page.page(output) print sys_exit, dump_file = opts.D[0] text_file = opts.T[0] if dump_file: dump_file = unquote_filename(dump_file) prof.dump_stats(dump_file) print '\n*** Profile stats marshalled to file',\ repr(dump_file)+'.',sys_exit if text_file: text_file = unquote_filename(text_file) pfile = open(text_file, 'w') pfile.write(output) pfile.close() print '\n*** Profile printout saved to text file',\ repr(text_file)+'.',sys_exit if 'r' in opts: return stats else: return None
class Inspector: def __init__(self, color_table, code_color_table, scheme, str_detail_level=0): self.color_table = color_table self.parser = PyColorize.Parser(code_color_table, out='str') self.format = self.parser.format self.str_detail_level = str_detail_level self.set_active_scheme(scheme) def __getdef(self, obj, oname=''): """Return the definition header for any callable object. If any exception is generated, None is returned instead and the exception is suppressed.""" try: return oname + inspect.formatargspec(*getargspec(obj)) except: return None def __head(self, h): """Return a header string with proper colors.""" return '%s%s%s' % (self.color_table.active_colors.header, h, self.color_table.active_colors.normal) def set_active_scheme(self, scheme): self.color_table.set_active_scheme(scheme) self.parser.color_table.set_active_scheme(scheme) def noinfo(self, msg, oname): """Generic message when no information is found.""" print 'No %s found' % msg, if oname: print 'for %s' % oname else: print def pdef(self, obj, oname=''): """Print the definition header for any callable object. If the object is a class, print the constructor information.""" if not callable(obj): print 'Object is not callable.' return header = '' if inspect.isclass(obj): header = self.__head('Class constructor information:\n') obj = obj.__init__ elif type(obj) is types.InstanceType: obj = obj.__call__ output = self.__getdef(obj, oname) if output is None: self.noinfo('definition header', oname) else: print >> Term.cout, header, self.format(output), 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.""" head = self.__head # so that itpl can find it even if private ds = getdoc(obj) if formatter: ds = formatter(ds) if inspect.isclass(obj): init_ds = getdoc(obj.__init__) output = itpl('$head("Class Docstring:")\n' '$indent(ds)\n' '$head("Constructor Docstring"):\n' '$indent(init_ds)') elif (type(obj) is types.InstanceType or isinstance(obj,object)) \ and hasattr(obj,'__call__'): call_ds = getdoc(obj.__call__) if call_ds: output = itpl('$head("Class Docstring:")\n$indent(ds)\n' '$head("Calling Docstring:")\n$indent(call_ds)') else: output = ds else: output = ds if output is None: self.noinfo('documentation', oname) return page(output) 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) except: self.noinfo('source', oname) else: page(self.format(src)) def pfile(self, obj, oname=''): """Show the whole file where an object was defined.""" try: try: lineno = inspect.getsourcelines(obj)[1] except TypeError: # For instances, try the class object like getsource() does if hasattr(obj, '__class__'): lineno = inspect.getsourcelines(obj.__class__)[1] # Adjust the inspected object so getabsfile() below works obj = obj.__class__ except: self.noinfo('file', oname) return # We only reach this point if object was successfully queried # run contents of file through pager starting at line # where the object is defined ofile = inspect.getabsfile(obj) if (ofile.endswith('.so') or ofile.endswith('.dll')): 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(self.format(open(ofile).read()), lineno - 1) def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0): """Show detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - formatter: special formatter for docstrings (see pdoc) - info: a structure with some information fields which may have been precomputed already. - detail_level: if set to 1, more information is given. """ obj_type = type(obj) header = self.__head if info is None: ismagic = 0 isalias = 0 ospace = '' else: ismagic = info.ismagic isalias = info.isalias ospace = info.namespace # Get docstring, special-casing aliases: if isalias: if not callable(obj): try: ds = "Alias to the system command:\n %s" % obj[1] except: ds = "Alias: " + str(obj) else: ds = "Alias to " + str(obj) if obj.__doc__: ds += "\nDocstring:\n" + obj.__doc__ else: ds = getdoc(obj) if ds is None: ds = '<no docstring>' if formatter is not None: ds = formatter(ds) # store output in a list which gets joined with \n at the end. out = myStringIO() string_max = 200 # max size of strings to show (snipped if longer) shalf = int((string_max - 5) / 2) if ismagic: obj_type_name = 'Magic function' elif isalias: obj_type_name = 'System alias' else: obj_type_name = obj_type.__name__ out.writeln(header('Type:\t\t') + obj_type_name) try: bclass = obj.__class__ out.writeln(header('Base Class:\t') + str(bclass)) except: pass # String form, but snip if too long in ? form (full in ??) if detail_level >= self.str_detail_level: try: ostr = str(obj) str_head = 'String Form:' if not detail_level and len(ostr) > string_max: ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:] ostr = ("\n" + " " * len(str_head.expandtabs())).\ join(map(string.strip,ostr.split("\n"))) if ostr.find('\n') > -1: # Print multi-line strings starting at the next line. str_sep = '\n' else: str_sep = '\t' out.writeln("%s%s%s" % (header(str_head), str_sep, ostr)) except: pass if ospace: out.writeln(header('Namespace:\t') + ospace) # Length (for strings and lists) try: length = str(len(obj)) out.writeln(header('Length:\t\t') + length) except: pass # Filename where object was defined binary_file = False try: try: fname = inspect.getabsfile(obj) except TypeError: # For an instance, the file that matters is where its class was # declared. if hasattr(obj, '__class__'): fname = inspect.getabsfile(obj.__class__) if fname.endswith('<string>'): fname = 'Dynamically generated function. No source code available.' if (fname.endswith('.so') or fname.endswith('.dll')): binary_file = True out.writeln(header('File:\t\t') + fname) except: # if anything goes wrong, we don't want to show source, so it's as # if the file was binary binary_file = True # reconstruct the function definition and print it: defln = self.__getdef(obj, oname) if defln: out.write(header('Definition:\t') + self.format(defln)) # Docstrings only in detail 0 mode, since source contains them (we # avoid repetitions). If source fails, we add them back, see below. if ds and detail_level == 0: out.writeln(header('Docstring:\n') + indent(ds)) # Original source code for any callable if detail_level: # Flush the source cache because inspect can return out-of-date # source linecache.checkcache() source_success = False try: try: src = getsource(obj, binary_file) except TypeError: if hasattr(obj, '__class__'): src = getsource(obj.__class__, binary_file) if src is not None: source = self.format(src) out.write(header('Source:\n') + source.rstrip()) source_success = True except Exception, msg: pass if ds and not source_success: out.writeln( header('Docstring [source file open failed]:\n') + indent(ds)) # Constructor docstring for classes if inspect.isclass(obj): # reconstruct the function definition and print it: try: obj_init = obj.__init__ except AttributeError: init_def = init_ds = None else: init_def = self.__getdef(obj_init, oname) init_ds = getdoc(obj_init) # Skip Python's auto-generated docstrings if init_ds and \ init_ds.startswith('x.__init__(...) initializes'): init_ds = None if init_def or init_ds: out.writeln(header('\nConstructor information:')) if init_def: out.write(header('Definition:\t') + self.format(init_def)) if init_ds: out.writeln(header('Docstring:\n') + indent(init_ds)) # and class docstring for instances: elif obj_type is types.InstanceType or \ isinstance(obj,object): # First, check whether the instance docstring is identical to the # class one, and print it separately if they don't coincide. In # most cases they will, but it's nice to print all the info for # objects which use instance-customized docstrings. if ds: try: cls = getattr(obj, '__class__') except: class_ds = None else: class_ds = getdoc(cls) # Skip Python's auto-generated docstrings if class_ds and \ (class_ds.startswith('function(code, globals[,') or \ class_ds.startswith('instancemethod(function, instance,') or \ class_ds.startswith('module(name[,') ): class_ds = None if class_ds and ds != class_ds: out.writeln( header('Class Docstring:\n') + indent(class_ds)) # Next, try to show constructor docstrings try: init_ds = getdoc(obj.__init__) # Skip Python's auto-generated docstrings if init_ds and \ init_ds.startswith('x.__init__(...) initializes'): init_ds = None except AttributeError: init_ds = None if init_ds: out.writeln( header('Constructor Docstring:\n') + indent(init_ds)) # Call form docstring for callable instances if hasattr(obj, '__call__'): #out.writeln(header('Callable:\t')+'Yes') call_def = self.__getdef(obj.__call__, oname) #if call_def is None: # out.writeln(header('Call def:\t')+ # 'Calling definition not available.') if call_def is not None: out.writeln(header('Call def:\t') + self.format(call_def)) call_ds = getdoc(obj.__call__) # Skip Python's auto-generated docstrings if call_ds and call_ds.startswith( 'x.__call__(...) <==> x(...)'): call_ds = None if call_ds: out.writeln(header('Call docstring:\n') + indent(call_ds)) # Finally send to printer/pager output = out.getvalue() if output: page(output)
def lprun(self, parameter_s=''): """ Execute a statement under the line-by-line profiler from the line_profiler module. Usage: %lprun -f func1 -f func2 <statement> The given statement (which doesn't require quote marks) is run via the LineProfiler. Profiling is enabled for the functions specified by the -f options. The statistics will be shown side-by-side with the code through the pager once the statement has completed. Options: -f <function>: LineProfiler only profiles functions and methods it is told to profile. This option tells the profiler about these functions. Multiple -f options may be used. The argument may be any expression that gives a Python function or method object. However, one must be careful to avoid spaces that may confuse the option parser. -m <module>: Get all the functions/methods in a module One or more -f or -m options are required to get any useful results. -D <filename>: dump the raw statistics out to a pickle file on disk. The usual extension for this is ".lprof". These statistics may be viewed later by running line_profiler.py as a script. -T <filename>: dump the text-formatted statistics with the code side-by-side out to a text file. -r: return the LineProfiler object after it has completed profiling. -s: strip out all entries from the print-out that have zeros. -u: specify time unit for the print-out in seconds. """ # Escape quote markers. opts_def = Struct(D=[''], T=[''], f=[], m=[], u=None) parameter_s = parameter_s.replace('"', r'\"').replace("'", r"\'") opts, arg_str = self.parse_options(parameter_s, 'rsf:m:D:T:u:', list_all=True) opts.merge(opts_def) global_ns = self.shell.user_global_ns local_ns = self.shell.user_ns # Get the requested functions. funcs = [] for name in opts.f: try: funcs.append(eval(name, global_ns, local_ns)) except Exception as e: raise UsageError('Could not find function %r.\n%s: %s' % (name, e.__class__.__name__, e)) profile = LineProfiler(*funcs) # Get the modules, too for modname in opts.m: try: mod = __import__(modname, fromlist=['']) profile.add_module(mod) except Exception as e: raise UsageError('Could not find module %r.\n%s: %s' % (modname, e.__class__.__name__, e)) if opts.u is not None: try: output_unit = float(opts.u[0]) except Exception as e: raise TypeError("Timer unit setting must be a float.") else: output_unit = None # Add the profiler to the builtins for @profile. if PY3: import builtins else: import __builtin__ as builtins if 'profile' in builtins.__dict__: had_profile = True old_profile = builtins.__dict__['profile'] else: had_profile = False old_profile = None builtins.__dict__['profile'] = profile try: try: profile.runctx(arg_str, global_ns, local_ns) message = '' except SystemExit: message = """*** SystemExit exception caught in code being profiled.""" except KeyboardInterrupt: message = ( "*** KeyboardInterrupt exception caught in code being " "profiled.") finally: if had_profile: builtins.__dict__['profile'] = old_profile # Trap text output. stdout_trap = StringIO() profile.print_stats(stdout_trap, output_unit=output_unit, stripzeros='s' in opts) output = stdout_trap.getvalue() output = output.rstrip() page(output) print(message, end="") dump_file = opts.D[0] if dump_file: profile.dump_stats(dump_file) print('\n*** Profile stats pickled to file %r. %s' % (dump_file, message)) text_file = opts.T[0] if text_file: pfile = open(text_file, 'w') pfile.write(output) pfile.close() print('\n*** Profile printout saved to text file %r. %s' % (text_file, message)) return_value = None if 'r' in opts: return_value = profile return return_value
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 doctest(elt): "Inline notebook popup for `show_test`" md = build_tests_markdown(elt) output = HTMLExporter().markdown2html(md) try: page.page({'text/html': output}) except: display(Markdown(md))
def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0): """Show detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - formatter: special formatter for docstrings (see pdoc) - 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.info(obj, oname=oname, formatter=formatter, info=info, detail_level=detail_level) displayfields = [] def add_fields(fields): for title, key in fields: field = info[key] if field is not None: displayfields.append((title, field.rstrip())) add_fields(self.pinfo_fields1) # Base class for old-style instances if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']: displayfields.append(("Base Class", info['base_class'].rstrip())) add_fields(self.pinfo_fields2) # Namespace if info['namespace'] != 'Interactive': displayfields.append(("Namespace", info['namespace'].rstrip())) add_fields(self.pinfo_fields3) # Source or docstring, depending on detail level and whether # source found. if detail_level > 0 and info['source'] is not None: displayfields.append(("Source", self.format(py3compat.cast_bytes_py2(info['source'])))) elif info['docstring'] is not None: displayfields.append(("Docstring", info["docstring"])) # Constructor info for classes if info['isclass']: if info['init_definition'] or info['init_docstring']: displayfields.append(("Constructor information", "")) if info['init_definition'] is not None: displayfields.append((" Definition", info['init_definition'].rstrip())) if info['init_docstring'] is not None: displayfields.append((" Docstring", indent(info['init_docstring']))) # Info for objects: else: add_fields(self.pinfo_fields_obj) # Finally send to printer/pager: if displayfields: page.page(self._format_fields(displayfields))
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:] if mode == 'rest': rest_docs = [] 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 = [""" IPython's 'magic' functions =========================== The magic function system provides a series of functions which allow you to control the behavior of 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 IPython), starting a new input with %% will automatically enter cell mode, and 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, IPython ships with automagic on, so you should only rarely need the % escape. Example: typing '%cd mydir' (without the quotes) changes you 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 quickref(self,arg): """ Show a quick reference sheet """ from IPython.core.usage import quick_reference qr = quick_reference + self._magic_docs(brief=True) page.page(qr)
def magic_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))
def info(cls, obj): if cls.options['info'] and not cls._disable_info_output: page.page(InfoPrinter.info(obj, ansi=True))
def quickref(self, arg): """ Show a quick reference sheet """ from IPython.core.usage import quick_reference qr = quick_reference + self.magic('-brief') page.page(qr)