diff --git a/IPython/kernel/zmq/session.py b/IPython/kernel/zmq/session.py index b71d043..2ba4738 100644 --- a/IPython/kernel/zmq/session.py +++ b/IPython/kernel/zmq/session.py @@ -436,8 +436,15 @@ class Session(Configurable): msg = dict(a=[1,'hi']) try: packed = pack(msg) - except Exception: - raise ValueError("packer could not serialize a simple message") + except Exception as e: + msg = "packer '{packer}' could not serialize a simple message: {e}{jsonmsg}" + if self.packer == 'json': + jsonmsg = "\nzmq.utils.jsonapi.jsonmod = %s" % jsonapi.jsonmod + else: + jsonmsg = "" + raise ValueError( + msg.format(packer=self.packer, e=e, jsonmsg=jsonmsg) + ) # ensure packed message is bytes if not isinstance(packed, bytes): @@ -446,8 +453,16 @@ class Session(Configurable): # check that unpack is pack's inverse try: unpacked = unpack(packed) - except Exception: - raise ValueError("unpacker could not handle the packer's output") + assert unpacked == msg + except Exception as e: + msg = "unpacker '{unpacker}' could not handle output from packer '{packer}': {e}{jsonmsg}" + if self.packer == 'json': + jsonmsg = "\nzmq.utils.jsonapi.jsonmod = %s" % jsonapi.jsonmod + else: + jsonmsg = "" + raise ValueError( + msg.format(packer=self.packer, unpacker=self.unpacker, e=e, jsonmsg=jsonmsg) + ) # check datetime support msg = dict(t=datetime.now()) diff --git a/IPython/kernel/zmq/tests/test_session.py b/IPython/kernel/zmq/tests/test_session.py index df7b77b..06b6d6f 100644 --- a/IPython/kernel/zmq/tests/test_session.py +++ b/IPython/kernel/zmq/tests/test_session.py @@ -20,6 +20,12 @@ from zmq.eventloop.zmqstream import ZMQStream from IPython.kernel.zmq import session as ss +def _bad_packer(obj): + raise TypeError("I don't work") + +def _bad_unpacker(bytes): + raise TypeError("I don't work either") + class SessionTestCase(BaseZMQTestCase): def setUp(self): @@ -222,4 +228,44 @@ class TestSession(SessionTestCase): self.assertTrue(len(session.digest_history) == 100) session._add_digest(uuid.uuid4().bytes) self.assertTrue(len(session.digest_history) == 91) - + + def test_bad_pack(self): + try: + session = ss.Session(pack=_bad_packer) + except ValueError as e: + self.assertIn("could not serialize", str(e)) + self.assertIn("don't work", str(e)) + else: + self.fail("Should have raised ValueError") + + def test_bad_unpack(self): + try: + session = ss.Session(unpack=_bad_unpacker) + except ValueError as e: + self.assertIn("could not handle output", str(e)) + self.assertIn("don't work either", str(e)) + else: + self.fail("Should have raised ValueError") + + def test_bad_packer(self): + try: + session = ss.Session(packer=__name__ + '._bad_packer') + except ValueError as e: + self.assertIn("could not serialize", str(e)) + self.assertIn("don't work", str(e)) + else: + self.fail("Should have raised ValueError") + + def test_bad_unpacker(self): + try: + session = ss.Session(unpacker=__name__ + '._bad_unpacker') + except ValueError as e: + self.assertIn("could not handle output", str(e)) + self.assertIn("don't work either", str(e)) + else: + self.fail("Should have raised ValueError") + + def test_bad_roundtrip(self): + with self.assertRaises(ValueError): + session= ss.Session(unpack=lambda b: 5) +