From 947ac4bc1f6f4016cf5baf2ecb4577e893bc3948 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Wed, 23 Aug 2017 18:07:37 +1000 Subject: [PATCH] py3: handle bytes in schema response If a server is running under py2 it could return a bytes value for the 'topic_topic' field in the schema response. A py3 client fails to handle this (in one place it applies 'str' to it, which raises BytesWarning; in other places it tries to serialise the schema to JSON which fails because of the bytes value). Handle the case where 'topic_topic' is not unicode, and handle bytes values when serialising the schema to JSON. Fixes: https://pagure.io/freeipa/issue/6809 Reviewed-By: Christian Heimes Reviewed-By: Stanislav Laznicka --- ipaclient/remote_plugins/schema.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py index efb479079..eb12d678b 100644 --- a/ipaclient/remote_plugins/schema.py +++ b/ipaclient/remote_plugins/schema.py @@ -64,6 +64,12 @@ _PARAMS = { } +def json_default(obj): + if isinstance(obj, bytes): + return obj.decode('utf-8') + raise TypeError + + class _SchemaCommand(ClientCommand): pass @@ -496,14 +502,14 @@ class Schema(object): ns = value for member in ns: path = '{}/{}'.format(key, member) - schema.writestr(path, - json.dumps(ns[member]).encode('utf-8')) + s = json.dumps(ns[member], default=json_default) + schema.writestr(path, s.encode('utf-8')) else: schema.writestr(key, json.dumps(value).encode('utf-8')) schema.writestr( '_help', - json.dumps(self._help).encode('utf-8') + json.dumps(self._help, default=json_default).encode('utf-8') ) def read_namespace_member(self, namespace, member): @@ -593,7 +599,10 @@ def get_package(server_info, client): module.__file__ = os.path.join(package_dir, '{}.py'.format(name)) module.__doc__ = topic.get('doc') if 'topic_topic' in topic: - module.topic = str(topic['topic_topic']).partition('/')[0] + s = topic['topic_topic'] + if isinstance(s, bytes): + s = s.decode('utf-8') + module.topic = s.partition('/')[0] else: module.topic = None