def magic_connect_info(self, arg_s): """Print information for connecting other clients to this kernel It will print the contents of this session's connection file, as well as shortcuts for local clients. In the simplest case, when called from the most recently launched kernel, secondary clients can be connected, simply with: $> ipython <app> --existing """ try: connection_file = get_connection_file() info = get_connection_info(unpack=False) except Exception as e: error("Could not get connection info: %r" % e) return print (info + '\n') print ("Paste the above JSON into a file, and connect with:\n" " $> ipython <app> --existing <file>\n" "or, if you are local, you can connect with just:\n" " $> ipython <app> --existing %s\n" "or even just:\n" " $> ipython <app> --existing\n" "if this is the most recent IPython session you have started." % os.path.basename(connection_file) )
def profile(self, parameter_s=''): """Print your currently active IPython profile.""" from IPython.core.application import BaseIPythonApplication if BaseIPythonApplication.initialized(): print(BaseIPythonApplication.instance().profile) else: error("profile is an application-level value, but you don't appear to be in an IPython application")
def inspect_error(): """Print a message about internal inspect errors. These are unfortunately quite common.""" error('Internal Python error in the inspect module.\n' 'Below is the traceback from this internal error.\n')
def gui(self, parameter_s=''): """Enable or disable IPython GUI event loop integration. %gui [GUINAME] This magic replaces IPython's threaded shells that were activated using the (pylab/wthread/etc.) command line flags. GUI toolkits can now be enabled at runtime and keyboard interrupts should work without any problems. The following toolkits are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX):: %gui wx # enable wxPython event loop integration %gui qt4|qt # enable PyQt4 event loop integration %gui gtk # enable PyGTK event loop integration %gui gtk3 # enable Gtk3 event loop integration %gui tk # enable Tk event loop integration %gui osx # enable Cocoa event loop integration # (requires %matplotlib 1.1) %gui # disable all event loop integration WARNING: after any of these has been called you can simply create an application object, but DO NOT start the event loop yourself, as we have already handled that. """ opts, arg = self.parse_options(parameter_s, '') if arg=='': arg = None try: return self.shell.enable_gui(arg) except Exception as e: # print simple error message, rather than traceback if we can't # hook up the GUI error(str(e))
def profile_missing_notice(self, *args, **kwargs): error( """\ The profile module could not be found. It has been removed from the standard python packages because of its non-free license. To use profiling, install the python-profiler package from non-free.""" )
def enable_pylab(self, gui=None, import_all=True): """Activate pylab support at runtime. This turns on support for matplotlib, preloads into the interactive namespace all of numpy and pylab, and configures IPython to correcdtly interact with the GUI event loop. The GUI backend to be used can be optionally selected with the optional :param:`gui` argument. Parameters ---------- gui : optional, string If given, dictates the choice of matplotlib GUI backend to use (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or 'gtk'), otherwise we use the default chosen by matplotlib (as dictated by the matplotlib build-time options plus the user's matplotlibrc configuration file). """ # We want to prevent the loading of pylab to pollute the user's # namespace as shown by the %who* magics, so we execute the activation # code in an empty namespace, and we update *both* user_ns and # user_ns_hidden with this information. ns = {} try: gui = pylab_activate(ns, gui, import_all) except KeyError: error("Backend %r not supported" % gui) return self.user_ns.update(ns) self.user_ns_hidden.update(ns) # Now we must activate the gui pylab wants to use, and fix %run to take # plot updates into account enable_gui(gui) self.magic_run = self._pylab_magic_run
def execute_command(options): global stdoutdata process = Popen(["mocodo"] + options, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdoutdata, stderrdata = process.communicate() status = process.wait() if status == 0 and stderrdata == "": return True error(stderrdata.strip())
def magic_paste(self, parameter_s=''): """Paste & execute a pre-formatted code block from clipboard. The text is pulled directly from the clipboard without user intervention and printed back on the screen before execution (unless the -q flag is given to force quiet mode). The block is dedented prior to execution to enable execution of method definitions. '>' and '+' characters at the beginning of a line are ignored, to allow pasting directly from e-mails, diff files and doctests (the '...' continuation prompt is also stripped). The executed block is also assigned to variable named 'pasted_block' for later editing with '%edit pasted_block'. You can also pass a variable name as an argument, e.g. '%paste foo'. This assigns the pasted block to variable 'foo' as string, without dedenting or executing it (preceding >>> and + is still stripped) Options ------- -r: re-executes the block previously entered by cpaste. -q: quiet mode: do not echo the pasted text back to the terminal. IPython statements (magics, shell escapes) are not supported (yet). See also -------- cpaste: manually paste code into terminal until you mark its end. """ opts,args = self.parse_options(parameter_s,'rq',mode='string') par = args.strip() if opts.has_key('r'): self._rerun_pasted() return try: text = self.shell.hooks.clipboard_get() block = self._strip_pasted_lines_for_code(text.splitlines()) except TryNext as clipboard_exc: message = getattr(clipboard_exc, 'args') if message: error(message[0]) else: error('Could not get text from the clipboard.') return # By default, echo back to terminal unless quiet mode is requested if not opts.has_key('q'): write = self.shell.write write(self.shell.pycolorize(block)) if not block.endswith('\n'): write('\n') write("## -- End pasted text --\n") self._execute_block(block, par)
def paste(self, parameter_s=""): """Paste & execute a pre-formatted code block from clipboard. The text is pulled directly from the clipboard without user intervention and printed back on the screen before execution (unless the -q flag is given to force quiet mode). The block is dedented prior to execution to enable execution of method definitions. '>' and '+' characters at the beginning of a line are ignored, to allow pasting directly from e-mails, diff files and doctests (the '...' continuation prompt is also stripped). The executed block is also assigned to variable named 'pasted_block' for later editing with '%edit pasted_block'. You can also pass a variable name as an argument, e.g. '%paste foo'. This assigns the pasted block to variable 'foo' as string, without executing it (preceding >>> and + is still stripped). Options: -r: re-executes the block previously entered by cpaste. -q: quiet mode: do not echo the pasted text back to the terminal. IPython statements (magics, shell escapes) are not supported (yet). See also -------- cpaste: manually paste code into terminal until you mark its end. """ opts, name = self.parse_options(parameter_s, "rq", mode="string") if "r" in opts: self.rerun_pasted() return try: block = self.shell.hooks.clipboard_get() except TryNext as clipboard_exc: message = getattr(clipboard_exc, "args") if message: error(message[0]) else: error("Could not get text from the clipboard.") return except ClipboardEmpty: raise UsageError("The clipboard appears to be empty") # By default, echo back to terminal unless quiet mode is requested if "q" not in opts: write = self.shell.write write(self.shell.pycolorize(block)) if not block.endswith("\n"): write("\n") write("## -- End pasted text --\n") self.store_or_execute(block, name)
def handle_sigint(self, *args): if self.shell._executing: if self.kernel_manager: self.kernel_manager.interrupt_kernel() else: self.shell.write_err('\n') error("Cannot interrupt kernels we didn't start.\n") else: # raise the KeyboardInterrupt if we aren't waiting for execution, # so that the interact loop advances, and prompt is redrawn, etc. raise KeyboardInterrupt
def magic_qtconsole(self, arg_s): """Open a qtconsole connected to this kernel. Useful for connecting a qtconsole to running notebooks, for better debugging. """ try: p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix')) except Exception as e: error("Could not start qtconsole: %r" % e) return
def rundot(s): """Execute dot and return a raw SVG image, or None.""" dot = Popen(['dot', '-Tsvg'], stdin=PIPE, stdout=PIPE, stderr=PIPE) stdoutdata, stderrdata = dot.communicate(s.encode('utf-8')) status = dot.wait() if status == 0: return stdoutdata else: fstr = "dot returned {}\n[==== stderr ====]\n{}" error(fstr.format(status, stderrdata.decode('utf-8'))) return None
def dotobj(self, line): """dot object magic""" obj = self.shell.ev(line) try: s = obj.to_dot() except AttributeError: error("expected object to implement 'to_dot()' method") else: data = rundot(s) if data: display_svg(data, raw=True)
def _from_obj(self, line, layout_engine): obj = self.shell.ev(line) try: s = obj.to_dot() except AttributeError: error("expected object to implement 'to_dot()' method") except TypeError: error("expected to_dot method to be callable w/o args") else: data = run_graphviz(s, layout_engine) if data: display_svg(data, raw=True)
def run_graphviz(s, layout_engine='dot'): """Execute dot with a layout and return a raw SVG image, or None.""" cmd = ['dot', '-Tsvg', '-K', layout_engine] dot = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdoutdata, stderrdata = dot.communicate(s.encode('utf-8')) status = dot.wait() if status == 0: return stdoutdata else: fstr = "dot returned {}\n[==== stderr ====]\n{}" error(fstr.format(status, stderrdata.decode('utf-8'))) return None
def dotobjs(self, line): """dot objects magic""" objs = self.shell.ev(line) for i, obj in enumerate(objs): try: s = obj.to_dot() except AttributeError: error("expected object to implement 'to_dot()' method") else: data = rundot(s) if data: info("object {}:".format(i)) display_svg(data, raw=True)
def profile(self, parameter_s=''): """Print your currently active IPython profile. See Also -------- prun : run code using the Python profiler (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`) """ warn("%profile is now deprecated. Please use get_ipython().profile instead.") from IPython.core.application import BaseIPythonApplication if BaseIPythonApplication.initialized(): print(BaseIPythonApplication.instance().profile) else: error("profile is an application-level value, but you don't appear to be in an IPython application")
def debugger(self, force=False): """Call the PuDB debugger.""" from IPython.utils.warn import error if not (force or self.call_pdb): return if not hasattr(sys, 'last_traceback'): error('No traceback has been produced, nothing to debug.') return from pudb import pm with self.readline_no_record: pm()
def magic_connect_info(self, arg_s): """Print information for connecting other clients to this kernel It will print the contents of this session's connection file, as well as shortcuts for local clients. In the simplest case, when called from the most recently launched kernel, secondary clients can be connected, simply with: $> ipython <app> --existing """ from IPython.core.application import BaseIPythonApplication as BaseIPApp if BaseIPApp.initialized(): app = BaseIPApp.instance() security_dir = app.profile_dir.security_dir profile = app.profile else: profile = 'default' security_dir = '' try: connection_file = get_connection_file() info = get_connection_info(unpack=False) except Exception as e: error("Could not get connection info: %r" % e) return # add profile flag for non-default profile profile_flag = "--profile %s" % profile if profile != 'default' else "" # if it's in the security dir, truncate to basename if security_dir == os.path.dirname(connection_file): connection_file = os.path.basename(connection_file) print (info + '\n') print ("Paste the above JSON into a file, and connect with:\n" " $> ipython <app> --existing <file>\n" "or, if you are local, you can connect with just:\n" " $> ipython <app> --existing {0} {1}\n" "or even just:\n" " $> ipython <app> --existing {1}\n" "if this is the most recent IPython session you have started.".format( connection_file, profile_flag ) )
def _from_objs(self, line, layout_engine): """dot objects magic""" objs = self.shell.ev(line) for i, obj in enumerate(objs): try: s = obj.to_dot() except AttributeError: error("expected object to implement 'to_dot()' method") except TypeError: error("expected to_dot method to be callable w/o args") else: data = run_graphviz(s, layout_engine) if data: info("object {}:".format(i)) display_svg(data, raw=True)
def runplantuml(s): """Execute plantuml and return a raw SVG image, or None.""" target_path = os.path.join(curpath(),'plantuml.jar') cmd = shlex.split('java -jar %s -Tsvg -p') cmd[2] = target_path plantuml = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdoutdata, stderrdata = plantuml.communicate(s.encode('utf-8')) status = plantuml.wait() if status == 0: return stdoutdata else: fstr = "plantuml returned {}\n[==== stderr ====]\n{}" error(fstr.format(status, stderrdata.decode('utf-8'))) return None
def remove(self,num): """Remove a finished (completed or dead) job.""" try: job = self.jobs_all[num] except KeyError: error('Job #%s not found' % num) else: stat_code = job.stat_code if stat_code == self._s_running: error('Job #%s is still running, it can not be removed.' % num) return elif stat_code == self._s_completed: self.jobs_comp.remove(job) elif stat_code == self._s_dead: self.jobs_dead.remove(job)
def handle_sigint(self, *args): if self.shell._executing: if self.kernel_manager: # interrupt already gets passed to subprocess by signal handler. # Only if we prevent that should we need to explicitly call # interrupt_kernel, until which time, this would result in a # double-interrupt: # self.kernel_manager.interrupt_kernel() pass else: self.shell.write_err('\n') error("Cannot interrupt kernels we didn't start.\n") else: # raise the KeyboardInterrupt if we aren't waiting for execution, # so that the interact loop advances, and prompt is redrawn, etc. raise KeyboardInterrupt
def ets(self, parameter_s=''): """Choose backend for ETS GUI %ets wx|qt """ opts, arg = self.parse_options(parameter_s, '') if arg == "qt": import sip, os sip.setapi('QString', 2) sip.setapi('QVariant', 2) os.environ['ETS_TOOLKIT'] = 'qt4' elif arg == "wx": import os os.environ['ETS_TOOLKIT'] = 'wx' else: from IPython.utils.warn import error error("argument of ets must be wx or qt") self.shell.enable_gui(arg)
def qtconsole(self, arg_s): """Open a qtconsole connected to this kernel. Useful for connecting a qtconsole to running notebooks, for better debugging. """ # %qtconsole should imply bind_kernel for engines: # FIXME: move to ipyparallel Kernel subclass if 'ipyparallel' in sys.modules: from ipyparallel import bind_kernel bind_kernel() try: p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix')) except Exception as e: error("Could not start qtconsole: %r" % e) return
def qtconsole(self, arg_s): """Open a qtconsole connected to this kernel. Useful for connecting a qtconsole to running notebooks, for better debugging. """ # %qtconsole should imply bind_kernel for engines: try: from IPython.parallel import bind_kernel except ImportError: # technically possible, because parallel has higher pyzmq min-version pass else: bind_kernel() try: p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix')) except Exception as e: error("Could not start qtconsole: %r" % e) return
def connect_info(self, arg_s): """Print information for connecting other clients to this kernel It will print the contents of this session's connection file, as well as shortcuts for local clients. In the simplest case, when called from the most recently launched kernel, secondary clients can be connected, simply with: $> jupyter <app> --existing """ try: connection_file = get_connection_file() info = get_connection_info(unpack=False) except Exception as e: error("Could not get connection info: %r" % e) return # if it's in the default dir, truncate to basename if jupyter_runtime_dir() == os.path.dirname(connection_file): connection_file = os.path.basename(connection_file) print (info + '\n') print ("Paste the above JSON into a file, and connect with:\n" " $> jupyter <app> --existing <file>\n" "or, if you are local, you can connect with just:\n" " $> jupyter <app> --existing {0}\n" "or even just:\n" " $> jupyter <app> --existing\n" "if this is the most recent Jupyter kernel you have started.".format( connection_file ) )
def flush_finished(self): """Flush all jobs finished (completed and dead) from lists. Running jobs are never flushed. It first calls _status_new(), to update info. If any jobs have completed since the last _status_new() call, the flush operation aborts.""" if self._status_new(): error('New jobs completed since last '\ '_status_new(), aborting flush.') return # Remove the finished jobs from the master dict jobs_all = self.jobs_all for job in self.jobs_comp+self.jobs_dead: del(jobs_all[job.num]) # Now flush these lists completely fl_comp = self._group_flush(self.jobs_comp,'Completed') fl_dead = self._group_flush(self.jobs_dead,'Dead') if not (fl_comp or fl_dead): print 'No jobs to flush.'
def run(self, parameter_s='', runner=None, file_finder=get_py_filename): """Run the named file inside IPython as a program. Usage:: %run [-n -i -e -G] [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )] ( -m mod | file ) [args] Parameters after the filename are passed as command-line arguments to the program (put in sys.argv). Then, control returns to IPython's prompt. This is similar to running at a system prompt ``python file args``, but with the advantage of giving you IPython's tracebacks, and of loading all variables into your interactive namespace for further use (unless -p is used, see below). The file is executed in a namespace initially consisting only of ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus sees its environment as if it were being run as a stand-alone program (except for sharing global objects such as previously imported modules). But after execution, the IPython interactive namespace gets updated with all variables defined in the program (except for __name__ and sys.argv). This allows for very convenient loading of code for interactive work, while giving each program a 'clean sheet' to run in. Arguments are expanded using shell-like glob match. Patterns '*', '?', '[seq]' and '[!seq]' can be used. Additionally, tilde '~' will be expanded into user's home directory. Unlike real shells, quotation does not suppress expansions. Use *two* back slashes (e.g. ``\\\\*``) to suppress expansions. To completely disable these expansions, you can use -G flag. Options: -n __name__ is NOT set to '__main__', but to the running file's name without extension (as python does under import). This allows running scripts and reloading the definitions in them without calling code protected by an ``if __name__ == "__main__"`` clause. -i run the file in IPython's namespace instead of an empty one. This is useful if you are experimenting with code written in a text editor which depends on variables defined interactively. -e ignore sys.exit() calls or SystemExit exceptions in the script being run. This is particularly useful if IPython is being used to run unittests, which always exit with a sys.exit() call. In such cases you are interested in the output of the test results, not in seeing a traceback of the unittest module. -t print timing information at the end of the run. IPython will give you an estimated CPU time consumption for your script, which under Unix uses the resource module to avoid the wraparound problems of time.clock(). Under Unix, an estimate of time spent on system tasks is also given (for Windows platforms this is reported as 0.0). If -t is given, an additional ``-N<N>`` option can be given, where <N> must be an integer indicating how many times you want the script to run. The final timing report will include total and per run results. For example (testing the script uniq_stable.py):: In [1]: run -t uniq_stable IPython CPU timings (estimated): User : 0.19597 s. System: 0.0 s. In [2]: run -t -N5 uniq_stable IPython CPU timings (estimated): Total runs performed: 5 Times : Total Per run User : 0.910862 s, 0.1821724 s. System: 0.0 s, 0.0 s. -d run your program under the control of pdb, the Python debugger. This allows you to execute your program step by step, watch variables, etc. Internally, what IPython does is similar to calling:: pdb.run('execfile("YOURFILENAME")') with a breakpoint set on line 1 of your file. You can change the line number for this automatic breakpoint to be <N> by using the -bN option (where N must be an integer). For example:: %run -d -b40 myscript will set the first breakpoint at line 40 in myscript.py. Note that the first breakpoint must be set on a line which actually does something (not a comment or docstring) for it to stop execution. Or you can specify a breakpoint in a different file:: %run -d -b myotherfile.py:20 myscript When the pdb debugger starts, you will see a (Pdb) prompt. You must first enter 'c' (without quotes) to start execution up to the first breakpoint. Entering 'help' gives information about the use of the debugger. You can easily see pdb's full documentation with "import pdb;pdb.help()" at a prompt. -p run program under the control of the Python profiler module (which prints a detailed report of execution times, function calls, etc). You can pass other options after -p which affect the behavior of the profiler itself. See the docs for %prun for details. In this mode, the program's variables do NOT propagate back to the IPython interactive namespace (because they remain in the namespace where the profiler executes them). Internally this triggers a call to %prun, see its documentation for details on the options available specifically for profiling. There is one special usage for which the text above doesn't apply: if the filename ends with .ipy, the file is run as ipython script, just as if the commands were written on IPython prompt. -m specify module name to load instead of script path. Similar to the -m option for the python interpreter. Use this option last if you want to combine with other %run options. Unlike the python interpreter only source modules are allowed no .pyc or .pyo files. For example:: %run -m example will run the example module. -G disable shell-like glob expansion of arguments. """ # get arguments and set sys.argv for program to be run. opts, arg_lst = self.parse_options(parameter_s, 'nidtN:b:pD:l:rs:T:em:G', mode='list', list_all=1) if "m" in opts: modulename = opts["m"][0] modpath = find_mod(modulename) if modpath is None: warn('%r is not a valid modulename on sys.path'%modulename) return arg_lst = [modpath] + arg_lst try: filename = file_finder(arg_lst[0]) except IndexError: warn('you must provide at least a filename.') print('\n%run:\n', oinspect.getdoc(self.run)) return except IOError as e: try: msg = str(e) except UnicodeError: msg = e.message error(msg) return if filename.lower().endswith('.ipy'): with preserve_keys(self.shell.user_ns, '__file__'): self.shell.user_ns['__file__'] = filename self.shell.safe_execfile_ipy(filename) return # Control the response to exit() calls made by the script being run exit_ignore = 'e' in opts # Make sure that the running script gets a proper sys.argv as if it # were run from a system shell. save_argv = sys.argv # save it for later restoring if 'G' in opts: args = arg_lst[1:] else: # tilde and glob expansion args = shellglob(map(os.path.expanduser, arg_lst[1:])) sys.argv = [filename] + args # put in the proper filename # protect sys.argv from potential unicode strings on Python 2: if not py3compat.PY3: sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ] if 'i' in opts: # Run in user's interactive namespace prog_ns = self.shell.user_ns __name__save = self.shell.user_ns['__name__'] prog_ns['__name__'] = '__main__' main_mod = self.shell.user_module # Since '%run foo' emulates 'python foo.py' at the cmd line, we must # set the __file__ global in the script's namespace # TK: Is this necessary in interactive mode? prog_ns['__file__'] = filename else: # Run in a fresh, empty namespace if 'n' in opts: name = os.path.splitext(os.path.basename(filename))[0] else: name = '__main__' # The shell MUST hold a reference to prog_ns so after %run # exits, the python deletion mechanism doesn't zero it out # (leaving dangling references). See interactiveshell for details main_mod = self.shell.new_main_mod(filename, name) prog_ns = main_mod.__dict__ # pickle fix. See interactiveshell for an explanation. But we need to # make sure that, if we overwrite __main__, we replace it at the end main_mod_name = prog_ns['__name__'] if main_mod_name == '__main__': restore_main = sys.modules['__main__'] else: restore_main = False # This needs to be undone at the end to prevent holding references to # every single object ever created. sys.modules[main_mod_name] = main_mod if 'p' in opts or 'd' in opts: if 'm' in opts: code = 'run_module(modulename, prog_ns)' code_ns = { 'run_module': self.shell.safe_run_module, 'prog_ns': prog_ns, 'modulename': modulename, } else: if 'd' in opts: # allow exceptions to raise in debug mode code = 'execfile(filename, prog_ns, raise_exceptions=True)' else: code = 'execfile(filename, prog_ns)' code_ns = { 'execfile': self.shell.safe_execfile, 'prog_ns': prog_ns, 'filename': get_py_filename(filename), } try: stats = None with self.shell.readline_no_record: if 'p' in opts: stats = self._run_with_profiler(code, opts, code_ns) else: if 'd' in opts: bp_file, bp_line = parse_breakpoint( opts.get('b', ['1'])[0], filename) self._run_with_debugger( code, code_ns, filename, bp_line, bp_file) else: if 'm' in opts: def run(): self.shell.safe_run_module(modulename, prog_ns) else: if runner is None: runner = self.default_runner if runner is None: runner = self.shell.safe_execfile def run(): runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) if 't' in opts: # timed execution try: nruns = int(opts['N'][0]) if nruns < 1: error('Number of runs must be >=1') return except (KeyError): nruns = 1 self._run_with_timing(run, nruns) else: # regular execution run() if 'i' in opts: self.shell.user_ns['__name__'] = __name__save else: # update IPython interactive namespace # Some forms of read errors on the file may mean the # __name__ key was never set; using pop we don't have to # worry about a possible KeyError. prog_ns.pop('__name__', None) with preserve_keys(self.shell.user_ns, '__file__'): self.shell.user_ns.update(prog_ns) finally: # It's a bit of a mystery why, but __builtins__ can change from # being a module to becoming a dict missing some key data after # %run. As best I can see, this is NOT something IPython is doing # at all, and similar problems have been reported before: # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html # Since this seems to be done by the interpreter itself, the best # we can do is to at least restore __builtins__ for the user on # exit. self.shell.user_ns['__builtins__'] = builtin_mod # Ensure key global structures are restored sys.argv = save_argv if restore_main: sys.modules['__main__'] = restore_main else: # Remove from sys.modules the reference to main_mod we'd # added. Otherwise it will trap references to objects # contained therein. del sys.modules[main_mod_name] return stats
def default_option(self, fn, optstr): """Make an entry in the options_table for fn, with value optstr""" if fn not in self.lsmagic(): error("%s is not a magic function" % fn) self.options_table[fn] = optstr
def run(self, parameter_s='', runner=None, file_finder=get_py_filename): """Run the named file inside IPython as a program. Usage:\\ %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args] Parameters after the filename are passed as command-line arguments to the program (put in sys.argv). Then, control returns to IPython's prompt. This is similar to running at a system prompt:\\ $ python file args\\ but with the advantage of giving you IPython's tracebacks, and of loading all variables into your interactive namespace for further use (unless -p is used, see below). The file is executed in a namespace initially consisting only of __name__=='__main__' and sys.argv constructed as indicated. It thus sees its environment as if it were being run as a stand-alone program (except for sharing global objects such as previously imported modules). But after execution, the IPython interactive namespace gets updated with all variables defined in the program (except for __name__ and sys.argv). This allows for very convenient loading of code for interactive work, while giving each program a 'clean sheet' to run in. Arguments are expanded using shell-like glob match. Patterns '*', '?', '[seq]' and '[!seq]' can be used. Additionally, tilde '~' will be expanded into user's home directory. Unlike real shells, quotation does not suppress expansions. Use *two* back slashes (e.g., '\\\\*') to suppress expansions. To completely disable these expansions, you can use -G flag. Options: -n: __name__ is NOT set to '__main__', but to the running file's name without extension (as python does under import). This allows running scripts and reloading the definitions in them without calling code protected by an ' if __name__ == "__main__" ' clause. -i: run the file in IPython's namespace instead of an empty one. This is useful if you are experimenting with code written in a text editor which depends on variables defined interactively. -e: ignore sys.exit() calls or SystemExit exceptions in the script being run. This is particularly useful if IPython is being used to run unittests, which always exit with a sys.exit() call. In such cases you are interested in the output of the test results, not in seeing a traceback of the unittest module. -t: print timing information at the end of the run. IPython will give you an estimated CPU time consumption for your script, which under Unix uses the resource module to avoid the wraparound problems of time.clock(). Under Unix, an estimate of time spent on system tasks is also given (for Windows platforms this is reported as 0.0). If -t is given, an additional -N<N> option can be given, where <N> must be an integer indicating how many times you want the script to run. The final timing report will include total and per run results. For example (testing the script uniq_stable.py):: In [1]: run -t uniq_stable IPython CPU timings (estimated):\\ User : 0.19597 s.\\ System: 0.0 s.\\ In [2]: run -t -N5 uniq_stable IPython CPU timings (estimated):\\ Total runs performed: 5\\ Times : Total Per run\\ User : 0.910862 s, 0.1821724 s.\\ System: 0.0 s, 0.0 s. -d: run your program under the control of pdb, the Python debugger. This allows you to execute your program step by step, watch variables, etc. Internally, what IPython does is similar to calling: pdb.run('execfile("YOURFILENAME")') with a breakpoint set on line 1 of your file. You can change the line number for this automatic breakpoint to be <N> by using the -bN option (where N must be an integer). For example:: %run -d -b40 myscript will set the first breakpoint at line 40 in myscript.py. Note that the first breakpoint must be set on a line which actually does something (not a comment or docstring) for it to stop execution. Or you can specify a breakpoint in a different file:: %run -d -b myotherfile.py:20 myscript When the pdb debugger starts, you will see a (Pdb) prompt. You must first enter 'c' (without quotes) to start execution up to the first breakpoint. Entering 'help' gives information about the use of the debugger. You can easily see pdb's full documentation with "import pdb;pdb.help()" at a prompt. -p: run program under the control of the Python profiler module (which prints a detailed report of execution times, function calls, etc). You can pass other options after -p which affect the behavior of the profiler itself. See the docs for %prun for details. In this mode, the program's variables do NOT propagate back to the IPython interactive namespace (because they remain in the namespace where the profiler executes them). Internally this triggers a call to %prun, see its documentation for details on the options available specifically for profiling. There is one special usage for which the text above doesn't apply: if the filename ends with .ipy, the file is run as ipython script, just as if the commands were written on IPython prompt. -m: specify module name to load instead of script path. Similar to the -m option for the python interpreter. Use this option last if you want to combine with other %run options. Unlike the python interpreter only source modules are allowed no .pyc or .pyo files. For example:: %run -m example will run the example module. -G: disable shell-like glob expansion of arguments. """ # get arguments and set sys.argv for program to be run. opts, arg_lst = self.parse_options(parameter_s, 'nidtN:b:pD:l:rs:T:em:G', mode='list', list_all=1) if "m" in opts: modulename = opts["m"][0] modpath = find_mod(modulename) if modpath is None: warn('%r is not a valid modulename on sys.path'%modulename) return arg_lst = [modpath] + arg_lst try: filename = file_finder(arg_lst[0]) except IndexError: warn('you must provide at least a filename.') print '\n%run:\n', oinspect.getdoc(self.run) return except IOError as e: try: msg = str(e) except UnicodeError: msg = e.message error(msg) return if filename.lower().endswith('.ipy'): with preserve_keys(self.shell.user_ns, '__file__'): self.shell.user_ns['__file__'] = filename self.shell.safe_execfile_ipy(filename) return # Control the response to exit() calls made by the script being run exit_ignore = 'e' in opts # Make sure that the running script gets a proper sys.argv as if it # were run from a system shell. save_argv = sys.argv # save it for later restoring if 'G' in opts: args = arg_lst[1:] else: # tilde and glob expansion args = shellglob(map(os.path.expanduser, arg_lst[1:])) sys.argv = [filename] + args # put in the proper filename # protect sys.argv from potential unicode strings on Python 2: if not py3compat.PY3: sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ] if 'i' in opts: # Run in user's interactive namespace prog_ns = self.shell.user_ns __name__save = self.shell.user_ns['__name__'] prog_ns['__name__'] = '__main__' main_mod = self.shell.new_main_mod(prog_ns) else: # Run in a fresh, empty namespace if 'n' in opts: name = os.path.splitext(os.path.basename(filename))[0] else: name = '__main__' main_mod = self.shell.new_main_mod() prog_ns = main_mod.__dict__ prog_ns['__name__'] = name # Since '%run foo' emulates 'python foo.py' at the cmd line, we must # set the __file__ global in the script's namespace prog_ns['__file__'] = filename # pickle fix. See interactiveshell for an explanation. But we need to # make sure that, if we overwrite __main__, we replace it at the end main_mod_name = prog_ns['__name__'] if main_mod_name == '__main__': restore_main = sys.modules['__main__'] else: restore_main = False # This needs to be undone at the end to prevent holding references to # every single object ever created. sys.modules[main_mod_name] = main_mod try: stats = None with self.shell.readline_no_record: if 'p' in opts: stats = self.prun('', None, False, opts, arg_lst, prog_ns) else: if 'd' in opts: deb = debugger.Pdb(self.shell.colors) # reset Breakpoint state, which is moronically kept # in a class bdb.Breakpoint.next = 1 bdb.Breakpoint.bplist = {} bdb.Breakpoint.bpbynumber = [None] # Set an initial breakpoint to stop execution maxtries = 10 bp_file, bp_line = parse_breakpoint(opts.get('b', [1])[0], filename) checkline = deb.checkline(bp_file, bp_line) if not checkline: for bp in range(bp_line + 1, bp_line + maxtries + 1): if deb.checkline(bp_file, bp): break else: msg = ("\nI failed to find a valid line to set " "a breakpoint\n" "after trying up to line: %s.\n" "Please set a valid breakpoint manually " "with the -b option." % bp) error(msg) return # if we find a good linenumber, set the breakpoint deb.do_break('%s:%s' % (bp_file, bp_line)) # Mimic Pdb._runscript(...) deb._wait_for_mainpyfile = True deb.mainpyfile = deb.canonic(filename) # Start file run print "NOTE: Enter 'c' at the", print "%s prompt to start your script." % deb.prompt ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns} try: #save filename so it can be used by methods on the deb object deb._exec_filename = filename deb.run('execfile("%s", prog_ns)' % filename, ns) except: etype, value, tb = sys.exc_info() # Skip three frames in the traceback: the %run one, # one inside bdb.py, and the command-line typed by the # user (run by exec in pdb itself). self.shell.InteractiveTB(etype, value, tb, tb_offset=3) else: if runner is None: runner = self.default_runner if runner is None: runner = self.shell.safe_execfile if 't' in opts: # timed execution try: nruns = int(opts['N'][0]) if nruns < 1: error('Number of runs must be >=1') return except (KeyError): nruns = 1 twall0 = time.time() if nruns == 1: t0 = clock2() runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) t1 = clock2() t_usr = t1[0] - t0[0] t_sys = t1[1] - t0[1] print "\nIPython CPU timings (estimated):" print " User : %10.2f s." % t_usr print " System : %10.2f s." % t_sys else: runs = range(nruns) t0 = clock2() for nr in runs: runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) t1 = clock2() t_usr = t1[0] - t0[0] t_sys = t1[1] - t0[1] print "\nIPython CPU timings (estimated):" print "Total runs performed:", nruns print " Times : %10.2f %10.2f" % ('Total', 'Per run') print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns) print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns) twall1 = time.time() print "Wall time: %10.2f s." % (twall1 - twall0) else: # regular execution runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) if 'i' in opts: self.shell.user_ns['__name__'] = __name__save else: # The shell MUST hold a reference to prog_ns so after %run # exits, the python deletion mechanism doesn't zero it out # (leaving dangling references). self.shell.cache_main_mod(prog_ns, filename) # update IPython interactive namespace # Some forms of read errors on the file may mean the # __name__ key was never set; using pop we don't have to # worry about a possible KeyError. prog_ns.pop('__name__', None) with preserve_keys(self.shell.user_ns, '__file__'): self.shell.user_ns.update(prog_ns) finally: # It's a bit of a mystery why, but __builtins__ can change from # being a module to becoming a dict missing some key data after # %run. As best I can see, this is NOT something IPython is doing # at all, and similar problems have been reported before: # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html # Since this seems to be done by the interpreter itself, the best # we can do is to at least restore __builtins__ for the user on # exit. self.shell.user_ns['__builtins__'] = builtin_mod # Ensure key global structures are restored sys.argv = save_argv if restore_main: sys.modules['__main__'] = restore_main else: # Remove from sys.modules the reference to main_mod we'd # added. Otherwise it will trap references to objects # contained therein. del sys.modules[main_mod_name] return stats
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 result(self,num): """result(N) -> return the result of job N.""" try: return self.all[num].result except KeyError: error('Job #%s not found' % num)
def profile_missing_notice(self, *args, **kwargs): error("""\ The profile module could not be found. It has been removed from the standard python packages because of its non-free license. To use profiling, install the python-profiler package from non-free.""")
def _traceback(self, job): num = job if isinstance(job, int) else job.num try: self.all[num].traceback() except KeyError: error('Job #%s not found' % num)
def config(self, s): """configure IPython %config Class[.trait=value] This magic exposes most of the IPython config system. Any Configurable class should be able to be configured with the simple line:: %config Class.trait=value Where `value` will be resolved in the user's namespace, if it is an expression or variable name. Examples -------- To see what classes are available for config, pass no arguments:: In [1]: %config Available objects for config: TerminalInteractiveShell HistoryManager PrefilterManager AliasManager IPCompleter PromptManager DisplayFormatter To view what is configurable on a given class, just pass the class name:: In [2]: %config IPCompleter IPCompleter options ----------------- IPCompleter.omit__names=<Enum> Current: 2 Choices: (0, 1, 2) Instruct the completer to omit private method names Specifically, when completing on ``object.<tab>``. When 2 [default]: all names that start with '_' will be excluded. When 1: all 'magic' names (``__foo__``) will be excluded. When 0: nothing will be excluded. IPCompleter.merge_completions=<CBool> Current: True Whether to merge completion results into a single list If False, only the completion results from the first non-empty completer will be returned. IPCompleter.limit_to__all__=<CBool> Current: False Instruct the completer to use __all__ for the completion Specifically, when completing on ``object.<tab>``. When True: only those names in obj.__all__ will be included. When False [default]: the __all__ attribute is ignored IPCompleter.greedy=<CBool> Current: False Activate greedy completion This will enable completion on elements of lists, results of function calls, etc., but can be unsafe because the code is actually evaluated on TAB. but the real use is in setting values:: In [3]: %config IPCompleter.greedy = True and these values are read from the user_ns if they are variables:: In [4]: feeling_greedy=False In [5]: %config IPCompleter.greedy = feeling_greedy """ from IPython.config.loader import Config # some IPython objects are Configurable, but do not yet have # any configurable traits. Exclude them from the effects of # this magic, as their presence is just noise: configurables = [ c for c in self.shell.configurables if c.__class__.class_traits(config=True) ] classnames = [c.__class__.__name__ for c in configurables] line = s.strip() if not line: # print available configurable names print("Available objects for config:") for name in classnames: print(" ", name) return elif line in classnames: # `%config TerminalInteractiveShell` will print trait info for # TerminalInteractiveShell c = configurables[classnames.index(line)] cls = c.__class__ help = cls.class_get_help(c) # strip leading '--' from cl-args: help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) print(help) return elif reg.match(line): cls, attr = line.split('.') return getattr(configurables[classnames.index(cls)], attr) elif '=' not in line: msg = "Invalid config statement: %r, "\ "should be `Class.trait = value`." ll = line.lower() for classname in classnames: if ll == classname.lower(): msg = msg + '\nDid you mean %s (note the case)?' % classname break raise UsageError(msg % line) # otherwise, assume we are setting configurables. # leave quotes on args when splitting, because we want # unquoted args to eval in user_ns cfg = Config() exec("cfg." + line, locals(), self.shell.user_ns) for configurable in configurables: try: configurable.update_config(cfg) except Exception as e: error(e)
def structured_traceback(self, etype, evalue, etb, tb_offset=None, context=5): """Return a nice text document describing the traceback.""" tb_offset = self.tb_offset if tb_offset is None else tb_offset # some locals try: etype = etype.__name__ except AttributeError: pass Colors = self.Colors # just a shorthand + quicker name lookup ColorsNormal = Colors.Normal # used a lot col_scheme = self.color_scheme_table.active_scheme_name indent = ' '*INDENT_SIZE em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal) undefined = '%sundefined%s' % (Colors.em, ColorsNormal) exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal) # some internal-use functions def text_repr(value): """Hopefully pretty robust repr equivalent.""" # this is pretty horrible but should always return *something* try: return pydoc.text.repr(value) except KeyboardInterrupt: raise except: try: return repr(value) except KeyboardInterrupt: raise except: try: # all still in an except block so we catch # getattr raising name = getattr(value, '__name__', None) if name: # ick, recursion return text_repr(name) klass = getattr(value, '__class__', None) if klass: return '%s instance' % text_repr(klass) except KeyboardInterrupt: raise except: return 'UNRECOVERABLE REPR FAILURE' def eqrepr(value, repr=text_repr): return '=%s' % repr(value) def nullrepr(value, repr=text_repr): return '' # meat of the code begins try: etype = etype.__name__ except AttributeError: pass if self.long_header: # Header with the exception type, python version, and date pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable date = time.ctime(time.time()) head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal, exc, ' '*(75-len(str(etype))-len(pyver)), pyver, date.rjust(75) ) head += "\nA problem occured executing Python code. Here is the sequence of function"\ "\ncalls leading up to the error, with the most recent (innermost) call last." else: # Simplified header head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc, 'Traceback (most recent call last)'.\ rjust(75 - len(str(etype)) ) ) frames = [] # Flush cache before calling inspect. This helps alleviate some of the # problems with python 2.3's inspect.py. ##self.check_cache() # Drop topmost frames if requested try: # Try the default getinnerframes and Alex's: Alex's fixes some # problems, but it generates empty tracebacks for console errors # (5 blanks lines) where none should be returned. #records = inspect.getinnerframes(etb, context)[tb_offset:] #print 'python records:', records # dbg records = _fixed_getinnerframes(etb, context, tb_offset) #print 'alex records:', records # dbg except: # FIXME: I've been getting many crash reports from python 2.3 # users, traceable to inspect.py. If I can find a small test-case # to reproduce this, I should either write a better workaround or # file a bug report against inspect (if that's the real problem). # So far, I haven't been able to find an isolated example to # reproduce the problem. inspect_error() traceback.print_exc(file=self.ostream) info('\nUnfortunately, your original traceback can not be constructed.\n') return '' # build some color string templates outside these nested loops tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal) tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal) tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ (Colors.vName, Colors.valEm, ColorsNormal) tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal) tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal, Colors.vName, ColorsNormal) tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal) tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line, ColorsNormal) # now, loop over all records printing context and info abspath = os.path.abspath for frame, file, lnum, func, lines, index in records: #print '*** record:',file,lnum,func,lines,index # dbg if not file: file = '?' elif not(file.startswith(str("<")) and file.endswith(str(">"))): # Guess that filenames like <string> aren't real filenames, so # don't call abspath on them. try: file = abspath(file) except OSError: # Not sure if this can still happen: abspath now works with # file names like <string> pass file = py3compat.cast_unicode(file, util_path.fs_encoding) link = tpl_link % file args, varargs, varkw, locals = inspect.getargvalues(frame) if func == '?': call = '' else: # Decide whether to include variable details or not var_repr = self.include_vars and eqrepr or nullrepr try: call = tpl_call % (func,inspect.formatargvalues(args, varargs, varkw, locals,formatvalue=var_repr)) except KeyError: # This happens in situations like errors inside generator # expressions, where local variables are listed in the # line, but can't be extracted from the frame. I'm not # 100% sure this isn't actually a bug in inspect itself, # but since there's no info for us to compute with, the # best we can do is report the failure and move on. Here # we must *not* call any traceback construction again, # because that would mess up use of %debug later on. So we # simply report the failure and move on. The only # limitation will be that this frame won't have locals # listed in the call signature. Quite subtle problem... # I can't think of a good way to validate this in a unit # test, but running a script consisting of: # dict( (k,v.strip()) for (k,v) in range(10) ) # will illustrate the error, if this exception catch is # disabled. call = tpl_call_fail % func # Don't attempt to tokenize binary files. if file.endswith(('.so', '.pyd', '.dll')): frames.append('%s %s\n' % (link,call)) continue elif file.endswith(('.pyc','.pyo')): # Look up the corresponding source file. file = openpy.source_from_cache(file) def linereader(file=file, lnum=[lnum], getline=ulinecache.getline): line = getline(file, lnum[0]) lnum[0] += 1 return line # Build the list of names on this line of code where the exception # occurred. try: names = [] name_cont = False for token_type, token, start, end, line in generate_tokens(linereader): # build composite names if token_type == tokenize.NAME and token not in keyword.kwlist: if name_cont: # Continuation of a dotted name try: names[-1].append(token) except IndexError: names.append([token]) name_cont = False else: # Regular new names. We append everything, the caller # will be responsible for pruning the list later. It's # very tricky to try to prune as we go, b/c composite # names can fool us. The pruning at the end is easy # to do (or the caller can print a list with repeated # names if so desired. names.append([token]) elif token == '.': name_cont = True elif token_type == tokenize.NEWLINE: break except (IndexError, UnicodeDecodeError): # signals exit of tokenizer pass except tokenize.TokenError as msg: _m = ("An unexpected error occurred while tokenizing input\n" "The following traceback may be corrupted or invalid\n" "The error message is: %s\n" % msg) error(_m) # Join composite names (e.g. "dict.fromkeys") names = ['.'.join(n) for n in names] # prune names list of duplicates, but keep the right order unique_names = uniq_stable(names) # Start loop over vars lvals = [] if self.include_vars: for name_full in unique_names: name_base = name_full.split('.',1)[0] if name_base in frame.f_code.co_varnames: if name_base in locals: try: value = repr(eval(name_full,locals)) except: value = undefined else: value = undefined name = tpl_local_var % name_full else: if name_base in frame.f_globals: try: value = repr(eval(name_full,frame.f_globals)) except: value = undefined else: value = undefined name = tpl_global_var % name_full lvals.append(tpl_name_val % (name,value)) if lvals: lvals = '%s%s' % (indent,em_normal.join(lvals)) else: lvals = '' level = '%s %s\n' % (link,call) if index is None: frames.append(level) else: frames.append('%s%s' % (level,''.join( _format_traceback_lines(lnum,index,lines,Colors,lvals, col_scheme)))) # Get (safely) a string form of the exception info try: etype_str,evalue_str = list(map(str,(etype,evalue))) except: # User exception is improperly defined. etype,evalue = str,sys.exc_info()[:2] etype_str,evalue_str = list(map(str,(etype,evalue))) # ... and format it exception = ['%s%s%s: %s' % (Colors.excName, etype_str, ColorsNormal, py3compat.cast_unicode(evalue_str))] if (not py3compat.PY3) and type(evalue) is types.InstanceType: try: names = [w for w in dir(evalue) if isinstance(w, str)] except: # Every now and then, an object with funny inernals blows up # when dir() is called on it. We do the best we can to report # the problem and continue _m = '%sException reporting error (object with broken dir())%s:' exception.append(_m % (Colors.excName,ColorsNormal)) etype_str,evalue_str = list(map(str,sys.exc_info()[:2])) exception.append('%s%s%s: %s' % (Colors.excName,etype_str, ColorsNormal, py3compat.cast_unicode(evalue_str))) names = [] for name in names: value = text_repr(getattr(evalue, name)) exception.append('\n%s%s = %s' % (indent, name, value)) # vds: >> if records: filepath, lnum = records[-1][1:3] #print "file:", str(file), "linenb", str(lnum) # dbg filepath = os.path.abspath(filepath) ipinst = get_ipython() if ipinst is not None: ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) # vds: << # return all our info assembled as a single string # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) ) return [head] + frames + [''.join(exception[0])]
def interact(self, display_banner=None): """Closely emulate the interactive Python console.""" # batch run -> do not interact if self.exit_now: return if display_banner is None: display_banner = self.display_banner if isinstance(display_banner, string_types): self.show_banner(display_banner) elif display_banner: self.show_banner() more = False # run a non-empty no-op, so that we don't get a prompt until # we know the kernel is ready. This keeps the connection # message above the first prompt. if not self.wait_for_kernel(self.kernel_timeout): error("Kernel did not respond\n") return if self.has_readline: self.readline_startup_hook(self.pre_readline) hlen_b4_cell = self.readline.get_current_history_length() else: hlen_b4_cell = 0 # exit_now is set by a call to %Exit or %Quit, through the # ask_exit callback. while not self.exit_now: if not self.client.is_alive(): # kernel died, prompt for action or exit action = "restart" if self.manager else "wait for restart" ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y') if ans: if self.manager: self.manager.restart_kernel(True) self.wait_for_kernel(self.kernel_timeout) else: self.exit_now = True continue try: # protect prompt block from KeyboardInterrupt # when sitting on ctrl-C self.hooks.pre_prompt_hook() if more: try: prompt = self.prompt_manager.render('in2') except Exception: self.showtraceback() if self.autoindent: self.rl_do_indent = True else: try: prompt = self.separate_in + self.prompt_manager.render( 'in') except Exception: self.showtraceback() line = self.raw_input(prompt) if self.exit_now: # quick exit on sys.std[in|out] close break if self.autoindent: self.rl_do_indent = False except KeyboardInterrupt: #double-guard against keyboardinterrupts during kbdint handling try: self.write('\nKeyboardInterrupt\n') source_raw = self.input_splitter.source_raw_reset()[1] hlen_b4_cell = self._replace_rlhist_multiline( source_raw, hlen_b4_cell) more = False except KeyboardInterrupt: pass except EOFError: if self.autoindent: self.rl_do_indent = False if self.has_readline: self.readline_startup_hook(None) self.write('\n') self.exit() except bdb.BdbQuit: warn( 'The Python debugger has exited with a BdbQuit exception.\n' 'Because of how pdb handles the stack, it is impossible\n' 'for IPython to properly format this particular exception.\n' 'IPython will resume normal operation.') except: # exceptions here are VERY RARE, but they can be triggered # asynchronously by signal handlers, for example. self.showtraceback() else: self.input_splitter.push(line) more = self.input_splitter.push_accepts_more() if (self.SyntaxTB.last_syntax_error and self.autoedit_syntax): self.edit_syntax_error() if not more: source_raw = self.input_splitter.source_raw_reset()[1] hlen_b4_cell = self._replace_rlhist_multiline( source_raw, hlen_b4_cell) self.run_cell(source_raw) # Turn off the exit flag, so the mainloop can be restarted if desired self.exit_now = False
def soft_define_alias(self, name, cmd): """Define an alias, but don't raise on an AliasError.""" try: self.define_alias(name, cmd) except AliasError as e: error("Invalid alias: %s" % e)
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() 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
def run(self, parameter_s='', runner=None, file_finder=get_py_filename): """Run the named file inside IPython as a program. Usage:\\ %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args] Parameters after the filename are passed as command-line arguments to the program (put in sys.argv). Then, control returns to IPython's prompt. This is similar to running at a system prompt:\\ $ python file args\\ but with the advantage of giving you IPython's tracebacks, and of loading all variables into your interactive namespace for further use (unless -p is used, see below). The file is executed in a namespace initially consisting only of __name__=='__main__' and sys.argv constructed as indicated. It thus sees its environment as if it were being run as a stand-alone program (except for sharing global objects such as previously imported modules). But after execution, the IPython interactive namespace gets updated with all variables defined in the program (except for __name__ and sys.argv). This allows for very convenient loading of code for interactive work, while giving each program a 'clean sheet' to run in. Options: -n: __name__ is NOT set to '__main__', but to the running file's name without extension (as python does under import). This allows running scripts and reloading the definitions in them without calling code protected by an ' if __name__ == "__main__" ' clause. -i: run the file in IPython's namespace instead of an empty one. This is useful if you are experimenting with code written in a text editor which depends on variables defined interactively. -e: ignore sys.exit() calls or SystemExit exceptions in the script being run. This is particularly useful if IPython is being used to run unittests, which always exit with a sys.exit() call. In such cases you are interested in the output of the test results, not in seeing a traceback of the unittest module. -t: print timing information at the end of the run. IPython will give you an estimated CPU time consumption for your script, which under Unix uses the resource module to avoid the wraparound problems of time.clock(). Under Unix, an estimate of time spent on system tasks is also given (for Windows platforms this is reported as 0.0). If -t is given, an additional -N<N> option can be given, where <N> must be an integer indicating how many times you want the script to run. The final timing report will include total and per run results. For example (testing the script uniq_stable.py):: In [1]: run -t uniq_stable IPython CPU timings (estimated):\\ User : 0.19597 s.\\ System: 0.0 s.\\ In [2]: run -t -N5 uniq_stable IPython CPU timings (estimated):\\ Total runs performed: 5\\ Times : Total Per run\\ User : 0.910862 s, 0.1821724 s.\\ System: 0.0 s, 0.0 s. -d: run your program under the control of pdb, the Python debugger. This allows you to execute your program step by step, watch variables, etc. Internally, what IPython does is similar to calling: pdb.run('execfile("YOURFILENAME")') with a breakpoint set on line 1 of your file. You can change the line number for this automatic breakpoint to be <N> by using the -bN option (where N must be an integer). For example:: %run -d -b40 myscript will set the first breakpoint at line 40 in myscript.py. Note that the first breakpoint must be set on a line which actually does something (not a comment or docstring) for it to stop execution. When the pdb debugger starts, you will see a (Pdb) prompt. You must first enter 'c' (without quotes) to start execution up to the first breakpoint. Entering 'help' gives information about the use of the debugger. You can easily see pdb's full documentation with "import pdb;pdb.help()" at a prompt. -p: run program under the control of the Python profiler module (which prints a detailed report of execution times, function calls, etc). You can pass other options after -p which affect the behavior of the profiler itself. See the docs for %prun for details. In this mode, the program's variables do NOT propagate back to the IPython interactive namespace (because they remain in the namespace where the profiler executes them). Internally this triggers a call to %prun, see its documentation for details on the options available specifically for profiling. There is one special usage for which the text above doesn't apply: if the filename ends with .ipy, the file is run as ipython script, just as if the commands were written on IPython prompt. -m: specify module name to load instead of script path. Similar to the -m option for the python interpreter. Use this option last if you want to combine with other %run options. Unlike the python interpreter only source modules are allowed no .pyc or .pyo files. For example:: %run -m example will run the example module. """ # get arguments and set sys.argv for program to be run. opts, arg_lst = self.parse_options(parameter_s, 'nidtN:b:pD:l:rs:T:em:', mode='list', list_all=1) if "m" in opts: modulename = opts["m"][0] modpath = find_mod(modulename) if modpath is None: warn('%r is not a valid modulename on sys.path' % modulename) return arg_lst = [modpath] + arg_lst try: filename = file_finder(arg_lst[0]) except IndexError: warn('you must provide at least a filename.') print '\n%run:\n', oinspect.getdoc(self.run) return except IOError as e: try: msg = str(e) except UnicodeError: msg = e.message error(msg) return if filename.lower().endswith('.ipy'): self.shell.safe_execfile_ipy(filename) return # Control the response to exit() calls made by the script being run exit_ignore = 'e' in opts # Make sure that the running script gets a proper sys.argv as if it # were run from a system shell. save_argv = sys.argv # save it for later restoring # simulate shell expansion on arguments, at least tilde expansion args = [os.path.expanduser(a) for a in arg_lst[1:]] sys.argv = [filename] + args # put in the proper filename # protect sys.argv from potential unicode strings on Python 2: if not py3compat.PY3: sys.argv = [py3compat.cast_bytes(a) for a in sys.argv] if 'i' in opts: # Run in user's interactive namespace prog_ns = self.shell.user_ns __name__save = self.shell.user_ns['__name__'] prog_ns['__name__'] = '__main__' main_mod = self.shell.new_main_mod(prog_ns) else: # Run in a fresh, empty namespace if 'n' in opts: name = os.path.splitext(os.path.basename(filename))[0] else: name = '__main__' main_mod = self.shell.new_main_mod() prog_ns = main_mod.__dict__ prog_ns['__name__'] = name # Since '%run foo' emulates 'python foo.py' at the cmd line, we must # set the __file__ global in the script's namespace prog_ns['__file__'] = filename # pickle fix. See interactiveshell for an explanation. But we need to # make sure that, if we overwrite __main__, we replace it at the end main_mod_name = prog_ns['__name__'] if main_mod_name == '__main__': restore_main = sys.modules['__main__'] else: restore_main = False # This needs to be undone at the end to prevent holding references to # every single object ever created. sys.modules[main_mod_name] = main_mod try: stats = None with self.shell.readline_no_record: if 'p' in opts: stats = self.prun('', None, False, opts, arg_lst, prog_ns) else: if 'd' in opts: deb = debugger.Pdb(self.shell.colors) # reset Breakpoint state, which is moronically kept # in a class bdb.Breakpoint.next = 1 bdb.Breakpoint.bplist = {} bdb.Breakpoint.bpbynumber = [None] # Set an initial breakpoint to stop execution maxtries = 10 bp = int(opts.get('b', [1])[0]) checkline = deb.checkline(filename, bp) if not checkline: for bp in range(bp + 1, bp + maxtries + 1): if deb.checkline(filename, bp): break else: msg = ( "\nI failed to find a valid line to set " "a breakpoint\n" "after trying up to line: %s.\n" "Please set a valid breakpoint manually " "with the -b option." % bp) error(msg) return # if we find a good linenumber, set the breakpoint deb.do_break('%s:%s' % (filename, bp)) # Mimic Pdb._runscript(...) deb._wait_for_mainpyfile = True deb.mainpyfile = deb.canonic(filename) # Start file run print "NOTE: Enter 'c' at the", print "%s prompt to start your script." % deb.prompt ns = { 'execfile': py3compat.execfile, 'prog_ns': prog_ns } try: deb.run('execfile("%s", prog_ns)' % filename, ns) except: etype, value, tb = sys.exc_info() # Skip three frames in the traceback: the %run one, # one inside bdb.py, and the command-line typed by the # user (run by exec in pdb itself). self.shell.InteractiveTB(etype, value, tb, tb_offset=3) else: if runner is None: runner = self.default_runner if runner is None: runner = self.shell.safe_execfile if 't' in opts: # timed execution try: nruns = int(opts['N'][0]) if nruns < 1: error('Number of runs must be >=1') return except (KeyError): nruns = 1 twall0 = time.time() if nruns == 1: t0 = clock2() runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) t1 = clock2() t_usr = t1[0] - t0[0] t_sys = t1[1] - t0[1] print "\nIPython CPU timings (estimated):" print " User : %10.2f s." % t_usr print " System : %10.2f s." % t_sys else: runs = range(nruns) t0 = clock2() for nr in runs: runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) t1 = clock2() t_usr = t1[0] - t0[0] t_sys = t1[1] - t0[1] print "\nIPython CPU timings (estimated):" print "Total runs performed:", nruns print " Times : %10s %10s" % ('Total', 'Per run') print " User : %10.2f s, %10.2f s." % ( t_usr, t_usr / nruns) print " System : %10.2f s, %10.2f s." % ( t_sys, t_sys / nruns) twall1 = time.time() print "Wall time: %10.2f s." % (twall1 - twall0) else: # regular execution runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore) if 'i' in opts: self.shell.user_ns['__name__'] = __name__save else: # The shell MUST hold a reference to prog_ns so after %run # exits, the python deletion mechanism doesn't zero it out # (leaving dangling references). self.shell.cache_main_mod(prog_ns, filename) # update IPython interactive namespace # Some forms of read errors on the file may mean the # __name__ key was never set; using pop we don't have to # worry about a possible KeyError. prog_ns.pop('__name__', None) self.shell.user_ns.update(prog_ns) finally: # It's a bit of a mystery why, but __builtins__ can change from # being a module to becoming a dict missing some key data after # %run. As best I can see, this is NOT something IPython is doing # at all, and similar problems have been reported before: # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html # Since this seems to be done by the interpreter itself, the best # we can do is to at least restore __builtins__ for the user on # exit. self.shell.user_ns['__builtins__'] = builtin_mod # Ensure key global structures are restored sys.argv = save_argv if restore_main: sys.modules['__main__'] = restore_main else: # Remove from sys.modules the reference to main_mod we'd # added. Otherwise it will trap references to objects # contained therein. del sys.modules[main_mod_name] return stats