diff options
author | Jason Gerard DeRose <jderose@redhat.com> | 2008-11-19 16:11:23 -0700 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2008-11-19 16:11:23 -0700 |
commit | cfe4ec2175c42f208ae23401991febb8525bdd9b (patch) | |
tree | 0bc565767b5da75f7711cc350f00edcecef0e3fb | |
parent | 2478ccd357efa7c38cc4acbfe2bfab2f3a8bf0cd (diff) | |
download | freeipa-cfe4ec2175c42f208ae23401991febb8525bdd9b.tar.gz freeipa-cfe4ec2175c42f208ae23401991febb8525bdd9b.tar.xz freeipa-cfe4ec2175c42f208ae23401991febb8525bdd9b.zip |
Added util.xmlrpc_wrap(), util.xmlrpc_unwrap() functions an corresponding unit tests
-rw-r--r-- | ipalib/util.py | 64 | ||||
-rw-r--r-- | tests/test_ipalib/test_util.py | 38 |
2 files changed, 102 insertions, 0 deletions
diff --git a/ipalib/util.py b/ipalib/util.py index 89e2c5a74..60b9409fa 100644 --- a/ipalib/util.py +++ b/ipalib/util.py @@ -27,9 +27,12 @@ import imp import optparse import logging import time +from types import NoneType +from xmlrpclib import Binary import krbV + def xmlrpc_marshal(*args, **kw): """ Marshal (args, kw) into ((kw,) + args). @@ -56,6 +59,67 @@ def xmlrpc_unmarshal(*params): return (params[1:], kw) +def xmlrpc_wrap(value): + """ + Wrap all ``str`` in ``xmlrpclib.Binary``. + + Because ``xmlrpclib.dumps()`` will itself convert all ``unicode`` instances + into UTF-8 encoded ``str`` instances, we don't do it here. + + So in total, when encoding data for an XML-RPC request, the following + transformations occur: + + * All ``str`` instances are treated as binary data and are wrapped in + an ``xmlrpclib.Binary()`` instance. + + * Only ``unicode`` instances are treated as character data. They get + converted to UTF-8 encoded ``str`` instances (although as mentioned, + not by this function). + + Also see `xmlrpc_unwrap`. + """ + if type(value) in (list, tuple): + return tuple(xmlrpc_wrap(v) for v in value) + if type(value) is dict: + return dict( + (k, xmlrpc_wrap(v)) for (k, v) in value.iteritems() + ) + if type(value) is str: + return Binary(value) + assert type(value) in (unicode, int, float, bool, NoneType) + return value + + +def xmlrpc_unwrap(value, encoding='UTF-8'): + """ + Unwrap all ``xmlrpc.Binary``, decode all ``str`` into ``unicode``. + + When decoding data from an XML-RPC request, the following transformations + occur: + + * The binary payloads of all ``xmlrpclib.Binary`` instances are + returned as ``str`` instances. + + * All ``str`` instances are treated as UTF-8 encoded character data. + They are decoded and the resulting ``unicode`` instance is returned. + + Also see `xmlrpc_wrap`. + """ + if type(value) in (list, tuple): + return tuple(xmlrpc_unwrap(v, encoding) for v in value) + if type(value) is dict: + return dict( + (k, xmlrpc_unwrap(v, encoding)) for (k, v) in value.iteritems() + ) + if type(value) is str: + return value.decode(encoding) + if isinstance(value, Binary): + assert type(value.data) is str + return value.data + assert type(value) in (int, float, bool, NoneType) + return value + + def get_current_principal(): try: return krbV.default_context().default_ccache().principal().name diff --git a/tests/test_ipalib/test_util.py b/tests/test_ipalib/test_util.py index 6729fcda5..b75d6dc72 100644 --- a/tests/test_ipalib/test_util.py +++ b/tests/test_ipalib/test_util.py @@ -21,6 +21,7 @@ Test the `ipalib.util` module. """ +from xmlrpclib import Binary from tests.util import raises from ipalib import util @@ -49,6 +50,43 @@ def test_xmlrpc_unmarshal(): (('one', 'two'), dict(three=3, four=4)) +def test_xmlrpc_wrap(): + """ + Test the `ipalib.util.xmlrpc_wrap` function. + """ + f = util.xmlrpc_wrap + assert f([]) == tuple() + assert f({}) == dict() + b = f('hello') + assert isinstance(b, Binary) + assert b.data == 'hello' + u = f(u'hello') + assert type(u) is unicode + assert u == u'hello' + value = f([dict(one=False, two=u'hello'), None, 'hello']) + + +def test_xmlrpc_unwrap(): + """ + Test the `ipalib.util.xmlrpc_unwrap` function. + """ + f = util.xmlrpc_unwrap + assert f([]) == tuple() + assert f({}) == dict() + utf8_bytes = '\xd0\x9f\xd0\xb0\xd0\xb2\xd0\xb5\xd0\xbb' + unicode_chars = u'\u041f\u0430\u0432\u0435\u043b' + value = f(Binary(utf8_bytes)) + assert type(value) is str + assert value == utf8_bytes + value = f(utf8_bytes) + assert type(value) is unicode + assert value == unicode_chars + value = f([True, Binary('hello'), dict(one=1, two=utf8_bytes, three=None)]) + assert value == (True, 'hello', dict(one=1, two=unicode_chars, three=None)) + assert type(value[1]) is str + assert type(value[2]['two']) is unicode + + def test_make_repr(): """ Test the `ipalib.util.make_repr` function. |