From 0b80d263e2169e8017965ff7c8382bc71a915fa6 2012-05-27 21:39:37 From: MinRK <benjaminrk@gmail.com> Date: 2012-05-27 21:39:37 Subject: [PATCH] restore %result functionality It now does what it once did in the days of Twisted long ago: display the output of the most recent command (e.g. after async %px). --- diff --git a/IPython/extensions/parallelmagic.py b/IPython/extensions/parallelmagic.py index ec71138..47a3afa 100644 --- a/IPython/extensions/parallelmagic.py +++ b/IPython/extensions/parallelmagic.py @@ -36,7 +36,9 @@ Usage import ast import re +import sys +from IPython.core.display import display from IPython.core.error import UsageError from IPython.core.magic import Magics, magics_class, line_magic from IPython.testing.skipdoctest import skip_doctest @@ -53,7 +55,7 @@ NO_ACTIVE_VIEW = "Use activate() on a DirectView object to use it with magics." class ParallelMagics(Magics): """A set of magics useful when controlling a parallel IPython cluster. """ - + # A flag showing if autopx is activated or not _autopx = False # the current view used by the magics: @@ -66,23 +68,36 @@ class ParallelMagics(Magics): To use this a :class:`DirectView` instance must be created and then activated by calling its :meth:`activate` method. + + This lets you recall the results of %px computations after + asynchronous submission (view.block=False). Then you can do the following:: - In [23]: %result - Out[23]: <AsyncResult: unknown> + In [23]: %px os.getpid() + Async parallel execution on engine(s): all - In [22]: ar = %result 6 + In [24]: %result + [ 8] Out[10]: 60920 + [ 9] Out[10]: 60921 + [10] Out[10]: 60922 + [11] Out[10]: 60923 """ + if self.active_view is None: raise UsageError(NO_ACTIVE_VIEW) - + + stride = len(self.active_view) try: index = int(parameter_s) except: - index = None - result = self.active_view.get_result(index) - return result + index = -1 + msg_ids = self.active_view.history[stride * index:(stride * (index + 1)) or None] + + result = self.active_view.get_result(msg_ids) + + result.get() + self._display_result(result) @skip_doctest @line_magic @@ -106,11 +121,14 @@ class ParallelMagics(Magics): if self.active_view is None: raise UsageError(NO_ACTIVE_VIEW) - print "Parallel execution on engine(s): %s" % self.active_view.targets - result = self.active_view.execute(parameter_s, block=False) + + base = "Parallel" if self.active_view.block else "Async parallel" + print base + " execution on engine(s): %s" % self.active_view.targets + + result = self.active_view.execute(parameter_s, silent=False, block=False) if self.active_view.block: result.get() - self._maybe_display_output(result) + self._display_result(result) @skip_doctest @line_magic @@ -171,18 +189,21 @@ class ParallelMagics(Magics): def _display_result(self, result): """Display the output of a parallel result. - - If self.active_view.block is True, wait for the result - and display the result. Otherwise, this is a noop. """ + # flush iopub, just in case + rc = self.active_view.client + rc._flush_iopub(rc._iopub_socket) + if result._single_result: # single result stdouts = [result.stdout.rstrip()] stderrs = [result.stderr.rstrip()] + outputs = [result.outputs] else: stdouts = [s.rstrip() for s in result.stdout] stderrs = [s.rstrip() for s in result.stderr] - + outputs = [outs for outs in result.outputs] + results = result.get_dict() targets = self.active_view.targets @@ -190,10 +211,29 @@ class ParallelMagics(Magics): targets = [targets] elif targets == 'all': targets = self.active_view.client.ids - + + # republish stdout: if any(stdouts): for eid,stdout in zip(targets, stdouts): - print '[stdout:%i]'%eid, stdout + print '[stdout:%2i]' % eid, stdout + + # republish stderr: + if any(stderrs): + for eid,stderr in zip(targets, stderrs): + print >> sys.stderr, '[stderr:%2i]' % eid, stderr + + # republish displaypub output + for eid,e_outputs in zip(targets, outputs): + for output in e_outputs: + md = output['metadata'] or {} + md['engine'] = eid + self.shell.display_pub.publish(output['source'], output['data'], md) + + # finally, add pyout: + for eid in targets: + r = results[eid] + if r.pyout: + display(r) def pxrun_cell(self, raw_cell, store_history=False, silent=False): @@ -256,7 +296,7 @@ class ParallelMagics(Magics): self.shell.showtraceback() return True else: - self._maybe_display_output(result) + self._display_result(result) return False