As per John's request, this patch allows lossless round-tripping of Python datetime.datetime objects.
Unfortunately, the xmlrpclib dumps() and loads() functions use funny wrapper objects like xmlrpclib.DateTime rather than directly serializing to/from standard Python types like datetime.datetime. This makes lossless round-tripping pretty cumbersome to implement. Doing a loads(foo, use_datetime=True) would work, but the `use_datetime` kwarg is only available in Python2.5 and newer, so I instead extended my xml_wrap() and xml_unwrap() functions.
>From 92ce9fa408f4b2e05cb61e3e40498b56cb709960 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose <jder...@redhat.com> Date: Wed, 2 Dec 2009 21:41:24 -0700 Subject: [PATCH] Allow lossless round-trip of datetime objects over XML-RPC --- ipalib/rpc.py | 9 +++++++-- tests/test_ipalib/test_rpc.py | 28 +++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ipalib/rpc.py b/ipalib/rpc.py index 62f1d77..61af52d 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -35,7 +35,10 @@ import threading import socket import os import errno -from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy, Transport, ProtocolError +from datetime import datetime +from xmlrpclib import dumps, loads +from xmlrpclib import Binary, Fault, DateTime, ProtocolError +from xmlrpclib import ServerProxy, Transport import kerberos from ipalib.backend import Connectible from ipalib.errors import public_errors, PublicError, UnknownError, NetworkError @@ -89,7 +92,7 @@ def xml_wrap(value): ) if type(value) is str: return Binary(value) - assert type(value) in (unicode, int, float, bool, NoneType) + assert type(value) in (unicode, int, float, bool, datetime, NoneType) return value @@ -122,6 +125,8 @@ def xml_unwrap(value, encoding='UTF-8'): if isinstance(value, Binary): assert type(value.data) is str return value.data + if isinstance(value, DateTime): + return datetime(*value.timetuple()[0:6]) assert type(value) in (unicode, int, float, bool, NoneType) return value diff --git a/tests/test_ipalib/test_rpc.py b/tests/test_ipalib/test_rpc.py index d5dd38c..ea0620f 100644 --- a/tests/test_ipalib/test_rpc.py +++ b/tests/test_ipalib/test_rpc.py @@ -22,7 +22,8 @@ Test the `ipalib.rpc` module. """ import threading -from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy +from xmlrpclib import Binary, DateTime, Fault, dumps, loads, ServerProxy +from datetime import datetime from tests.util import raises, assert_equal, PluginTester, DummyClass from tests.data import binary_bytes, utf8_bytes, unicode_str from ipalib.frontend import Command @@ -53,6 +54,9 @@ def test_round_trip(): This tests the two functions together with ``xmlrpclib.dumps()`` and ``xmlrpclib.loads()`` in a full wrap/dumps/loads/unwrap round trip. """ + dt_utc = datetime.utcfromtimestamp(1234567890) + dt_loc = datetime.fromtimestamp(1234567890) + # We first test that our assumptions about xmlrpclib module in the Python # standard library are correct: assert_equal(dump_n_load(utf8_bytes), unicode_str) @@ -65,6 +69,13 @@ def test_round_trip(): assert_equal(dump_n_load(u''), '') assert dump_n_load(None) is None + dnl_utc = dump_n_load(dt_utc) + assert_equal(dnl_utc, DateTime(dt_utc)) + assert isinstance(dnl_utc, DateTime) + dnl_loc = dump_n_load(dt_loc) + assert_equal(dnl_loc, DateTime(1234567890)) + assert isinstance(dnl_loc, DateTime) + # Now we test our wrap and unwrap methods in combination with dumps, loads: # All str should come back str (because they get wrapped in # xmlrpclib.Binary(). All unicode should come back unicode because str @@ -78,8 +89,19 @@ def test_round_trip(): assert_equal(round_trip(''), '') assert_equal(round_trip(u''), u'') assert round_trip(None) is None - compound = [utf8_bytes, None, binary_bytes, (None, unicode_str), - dict(utf8=utf8_bytes, chars=unicode_str, data=binary_bytes) + + assert_equal(round_trip(dt_utc), dt_utc) + assert isinstance(dt_utc, datetime) + assert_equal(round_trip(dt_loc), dt_loc) + assert isinstance(dt_loc, datetime) + + compound = [utf8_bytes, None, binary_bytes, (None, unicode_str), dt_loc, + dict( + utf8=utf8_bytes, + chars=unicode_str, + data=binary_bytes, + datetime=dt_utc, + ), ] assert round_trip(compound) == tuple(compound) -- 1.6.3.3
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel