From e43a4a616858fbf747c79774b37a8e13a9521428 Mon Sep 17 00:00:00 2001 From: Yusei Tahara <yusei@nexedi.com> Date: Thu, 10 Jan 2008 17:37:47 +0000 Subject: [PATCH] Support reduce type object. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@18653 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Type/patches/ppml.py | 22 +++++++ product/ERP5Type/tests/testXMLPickle.py | 88 +++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 product/ERP5Type/tests/testXMLPickle.py diff --git a/product/ERP5Type/patches/ppml.py b/product/ERP5Type/patches/ppml.py index 09f2b7277e..bdeab926bc 100644 --- a/product/ERP5Type/patches/ppml.py +++ b/product/ERP5Type/patches/ppml.py @@ -662,6 +662,28 @@ def save_unicode(self, tag, data): ppml.save_unicode = save_unicode +def save_object(self, tag, data): + if len(data)==5: + #OBJECT + v='('+data[2] + x=data[3][1:] + stop=string.rfind(x,'t') # This seems + if stop>=0: x=x[:stop] # wrong! + v=save_put(self, v+x+'o', data[1]) + v=v+data[4]+'b' # state + return v + else: + #REDUCE + #data does not contain state.(See Object.__setstate__ definition) + #So, we can assume that this is a reduce. (Yusei) + v='('+data[2] + v=save_put(self, data[2]+data[3], data[1]) + v=v+'R' + return v + +ppml.save_object = save_object + + class xmlPickler(NoBlanks, xyap): # XXX fix a bug in xyap. def unknown_endtag(self, tag): diff --git a/product/ERP5Type/tests/testXMLPickle.py b/product/ERP5Type/tests/testXMLPickle.py new file mode 100644 index 0000000000..f22af31851 --- /dev/null +++ b/product/ERP5Type/tests/testXMLPickle.py @@ -0,0 +1,88 @@ +############################################################################## +# +# Copyright (c) 2008 Nexedi SARL and Contributors. All Rights Reserved. +# TAHARA Yusei <yusei@nexedi.com> +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +import unittest +import pickle +import re +import xml.parsers.pyexpat +from StringIO import StringIO +from Shared.DC.xml import ppml + + +class DummyClass: + """ + A dummy data class + """ + + def __init__(self): + self.data = [] + + +class TestXMLPickle(unittest.TestCase): + + def test_reduce(self): + """ + Make sure that a object which uses reduce for pickling can be pickled by xml pickler. + """ + obj = DummyClass() + obj.data.append(1) + obj.data.append(obj) + obj.data.append(obj.data) + + pattern = re.compile('WAA') # regex pattern object uses reduce.(See sre.py) + obj.data.append(pattern) + + pickled_string = pickle.dumps(obj) + xmldata = str(ppml.ToXMLloads(pickled_string)) + + output = StringIO() + + F=ppml.xmlPickler() + F.file = output + F.binary = 1 + + p=xml.parsers.pyexpat.ParserCreate() + p.CharacterDataHandler=F.handle_data + p.StartElementHandler=F.unknown_starttag + p.EndElementHandler=F.unknown_endtag + + r = p.Parse(xmldata) + + reconstructed_pickled_data = F._stack[0][0] + reconstructed_obj = pickle.loads(reconstructed_pickled_data) + + self.assert_(reconstructed_obj.__class__ is DummyClass) + self.assert_(type(getattr(reconstructed_obj, 'data', None)) is list) + self.assertEqual(reconstructed_obj.data[0], 1) + self.assert_(reconstructed_obj.data[1] is reconstructed_obj) + self.assert_(reconstructed_obj.data[2] is reconstructed_obj.data) + self.assert_(type(reconstructed_obj.data[3]) is type(pattern)) + self.assertEqual(reconstructed_obj.data[3].pattern, 'WAA') + +if __name__ == '__main__': + unittest.main() -- 2.30.9