From e8ab8d9352f8cb7bc7aaa1d467f94a5675109d88 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Fri, 5 Oct 2018 20:52:51 +0100 Subject: [PATCH] issue #72: add CallError.type_name, mitogen.core.qualname(). --- docs/internals.rst | 7 ++++--- mitogen/core.py | 22 +++++++++++++++++++--- tests/call_error_test.py | 13 ++++++++++--- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/docs/internals.rst b/docs/internals.rst index 03f12e1e..5ee285cb 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -334,12 +334,13 @@ Helper Functions ================ .. currentmodule:: mitogen.core -.. autofunction:: to_text .. autofunction:: has_parent_authority +.. autofunction:: io_op +.. autofunction:: qualname +.. autofunction:: set_block .. autofunction:: set_cloexec .. autofunction:: set_nonblock -.. autofunction:: set_block -.. autofunction:: io_op +.. autofunction:: to_text .. currentmodule:: mitogen.parent .. autofunction:: close_nonstandard_fds diff --git a/mitogen/core.py b/mitogen/core.py index dadf0924..597e0d90 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -236,6 +236,13 @@ class Kwargs(dict): return (Kwargs, (dict(self),)) +def qualname(type_): + """ + Given a type, return its fully qualified name as a string. + """ + return '%s.%s' % (type_.__module__, type_.__name__) + + class CallError(Error): """Serializable :class:`Error` subclass raised when :py:meth:`Context.call() ` fails. A copy of @@ -246,7 +253,7 @@ class CallError(Error): Error.__init__(self, fmt, *args) else: e = fmt - fmt = '%s.%s: %s' % (type(e).__module__, type(e).__name__, e) + fmt = '%s: %s' % (qualname(type(e)), e) args = () tb = sys.exc_info()[2] if tb: @@ -254,6 +261,16 @@ class CallError(Error): fmt += ''.join(traceback.format_tb(tb)) Error.__init__(self, fmt) + @property + def type_name(self): + """ + Return the fully qualified name of the original exception type, or + :data:`None` if the :class:`CallError` was raised explcitly. + """ + type_name, sep, _ = self.args[0].partition(':') + if sep: + return type_name + def __reduce__(self): return (_unpickle_call_error, (self.args[0],)) @@ -1205,8 +1222,7 @@ class Stream(BasicStream): self.transmit_side = Side(self, os.dup(wfd)) def __repr__(self): - cls = type(self) - return '%s.%s(%r)' % (cls.__module__, cls.__name__, self.name) + return '%s(%r)' % (qualname(type(self)), self.name) class Context(object): diff --git a/tests/call_error_test.py b/tests/call_error_test.py index 447a80a9..30893191 100644 --- a/tests/call_error_test.py +++ b/tests/call_error_test.py @@ -24,14 +24,16 @@ class ConstructorTest(unittest2.TestCase): def test_from_exc(self): ve = plain_old_module.MyError('eek') e = self.klass(ve) + self.assertEquals(e.type_name, 'plain_old_module.MyError') self.assertEquals(e.args[0], 'plain_old_module.MyError: eek') def test_form_base_exc(self): ve = SystemExit('eek') + type_name = mitogen.core.qualname(SystemExit) # varies across 2/3. + e = self.klass(ve) - self.assertEquals(e.args[0], - # varies across 2/3. - '%s.%s: eek' % (type(ve).__module__, type(ve).__name__)) + self.assertEquals(e.type_name, type_name) + self.assertEquals(e.args[0], '%s: eek' % (type_name,)) def test_from_exc_tb(self): try: @@ -40,6 +42,7 @@ class ConstructorTest(unittest2.TestCase): ve = sys.exc_info()[1] e = self.klass(ve) + self.assertTrue(e.type_name, 'plain_old_module.MyError') self.assertTrue(e.args[0].startswith('plain_old_module.MyError: eek')) self.assertTrue('test_from_exc_tb' in e.args[0]) @@ -50,17 +53,20 @@ class PickleTest(unittest2.TestCase): def test_string_noargs(self): e = self.klass('%s%s') e2 = pickle.loads(pickle.dumps(e)) + self.assertEquals(e2.type_name, None) self.assertEquals(e2.args[0], '%s%s') def test_string_args(self): e = self.klass('%s%s', 1, 1) e2 = pickle.loads(pickle.dumps(e)) + self.assertEquals(e2.type_name, None) self.assertEquals(e2.args[0], '11') def test_from_exc(self): ve = plain_old_module.MyError('eek') e = self.klass(ve) e2 = pickle.loads(pickle.dumps(e)) + self.assertEquals(e2.type_name, 'plain_old_module.MyError') self.assertEquals(e2.args[0], 'plain_old_module.MyError: eek') def test_from_exc_tb(self): @@ -71,6 +77,7 @@ class PickleTest(unittest2.TestCase): e = self.klass(ve) e2 = pickle.loads(pickle.dumps(e)) + self.assertEquals(e2.type_name, 'plain_old_module.MyError') self.assertTrue(e2.args[0].startswith('plain_old_module.MyError: eek')) self.assertTrue('test_from_exc_tb' in e2.args[0])