Repository: ipython/ipython

Issue:
 remote tracebacks broken since 952d0d6 (PR #2223)
since 952d0d68d22860bf55fca35c1573a77a4455a7ed PR #2223 broke remote tracebacks:

```
from IPython.parallel import Client
c = Client()
dv = c[:]
dv.execute("from nump import *").get()
```

outputs "No traceback available" instead of the tracebacks
this affects HEAD and the 0.13.1 branch



Discussion:
I also think this backport is not really appropriate for a bugfix branch

the issue was discovered by syamajala on irc who was following 0.13.1

We wouldn't normally backport something like that, but we felt the issue it
fixed was sufficiently serious to be worth applying to the 0.13 branch.
Thanks for reporting it before we do a 0.13.1.


Resolving patch:
diff --git a/IPython/parallel/error.py b/IPython/parallel/error.py
--- a/IPython/parallel/error.py
+++ b/IPython/parallel/error.py
@@ -194,9 +194,15 @@ 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"""
         print('\n'.join(self.render_traceback()))


Test patch:
diff --git a/IPython/parallel/tests/test_view.py b/IPython/parallel/tests/test_view.py
--- a/IPython/parallel/tests/test_view.py
+++ b/IPython/parallel/tests/test_view.py
@@ -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
@@ -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"""