Skip to content

Commit

Permalink
Backport PR #2305: RemoteError._render_traceback_ calls self.render_t…
Browse files Browse the repository at this point in the history
…raceback

rather than an alias

There are two options here:

1. `_render_traceback_`  should *call* render_traceback
2. any subclass that redefines render_traceback must also redefine `_render_traceback_`

I went with 1., which is more efficient code-wise when subclassing RemoteError
(would prevent future cases of this same mistake),
but less efficient execution-wise, because it involves an extra function call.

closes #2303
  • Loading branch information
minrk committed Sep 1, 2012
1 parent 25b5f87 commit 0e42613
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
10 changes: 8 additions & 2 deletions IPython/parallel/error.py
Expand Up @@ -194,8 +194,14 @@ def render_traceback(self):
"""render traceback to a list of lines"""
return (self.traceback or "No traceback available").splitlines()

# Special method for custom tracebacks within IPython
_render_traceback_ = render_traceback
def _render_traceback_(self):
"""Special method for custom tracebacks within IPython.
This will be called by IPython instead of displaying the local traceback.
It should return a traceback rendered as a list of lines.
"""
return self.render_traceback()

def print_traceback(self, excid=None):
"""print my traceback"""
Expand Down
25 changes: 25 additions & 0 deletions IPython/parallel/tests/test_view.py
Expand Up @@ -27,6 +27,7 @@

from IPython.testing import decorators as dec
from IPython.testing.ipunittest import ParametricTestCase
from IPython.utils.io import capture_output

from IPython import parallel as pmod
from IPython.parallel import error
Expand Down Expand Up @@ -578,6 +579,30 @@ def test_execute_raises(self):
ar = view.execute("1/0")
self.assertRaisesRemote(ZeroDivisionError, ar.get, 2)

def test_remoteerror_render_exception(self):
"""RemoteErrors get nice tracebacks"""
view = self.client[-1]
ar = view.execute("1/0")
ip = get_ipython()
ip.user_ns['ar'] = ar
with capture_output() as io:
ip.run_cell("ar.get(2)")

self.assertTrue('ZeroDivisionError' in io.stdout, io.stdout)

def test_compositeerror_render_exception(self):
"""CompositeErrors get nice tracebacks"""
view = self.client[:]
ar = view.execute("1/0")
ip = get_ipython()
ip.user_ns['ar'] = ar
with capture_output() as io:
ip.run_cell("ar.get(2)")

self.assertEqual(io.stdout.count('ZeroDivisionError'), len(view) * 2, io.stdout)
self.assertEqual(io.stdout.count('integer division'), len(view), io.stdout)
self.assertEqual(io.stdout.count(':execute'), len(view), io.stdout)

@dec.skipif_not_matplotlib
def test_magic_pylab(self):
"""%pylab works on engines"""
Expand Down

0 comments on commit 0e42613

Please sign in to comment.