XML_Marshaller : Instances are now correctly unmarshalled. Also added...

XML_Marshaller : Instances are now correctly unmarshalled. Also added changelog and cleaned setup.py.
parent e3158e70
0.9.4 (Unreleased)
----------------
- [fix] Instances are now correctly unmarshalled.
[Cedric de Saint Martin]
Marshals simple Python data types into a custom XML format.
The Marshaller and Unmarshaller classes can be subclassed in order
to implement marshalling into a different XML DTD.
Original Authors are XML-SIG (xml-sig@python.org).
Fully compatible with PyXML implementation, enable namespace support for
XML Input/Output.
Implemented with lxml
\ No newline at end of file
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from setuptools import setup, find_packages from setuptools import setup, find_packages
import sys, os
version = '0.9.3' name = 'xml_marshaller'
version = '0.9.4'
setup(name='xml_marshaller', def read(name):
return open(name).read()
long_description=(
read('README.txt')
+ '\n' +
read('CHANGES.txt')
)
setup(name=name,
version=version, version=version,
description="Converting Python objects to XML and back again.", description="Converting Python objects to XML and back again.",
long_description=""" long_description=long_description,
Marshals simple Python data types into a custom XML format. classifiers=['Development Status :: 4 - Beta',
The Marshaller and Unmarshaller classes can be subclassed in order
to implement marshalling into a different XML DTD.
Original Authors are XML-SIG (xml-sig@python.org).
Fully compatible with PyXML implementation, enable namespace support for
XML Input/Output.
Implemented with lxml""",
classifiers=['Development Status :: 4 - Beta',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: Python License (CNRI Python License)', 'License :: OSI Approved :: Python License (CNRI Python License)',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
......
...@@ -567,24 +567,15 @@ class Unmarshaller(ElementTreeContentHandler): ...@@ -567,24 +567,15 @@ class Unmarshaller(ElementTreeContentHandler):
def um_end_instance(self, name): def um_end_instance(self, name):
value, module, classname, initargs, kw = self.data_stack[-5:] value, module, classname, initargs, kw = self.data_stack[-5:]
klass = self.find_class(module, classname) klass = self.find_class(module, classname)
instantiated = 0
if (not initargs and (isinstance(klass, (ClassType, TypeType))) and if (not initargs and (isinstance(klass, (ClassType, TypeType))) and
not hasattr(klass, '__getinitargs__')): not hasattr(klass, '__getinitargs__')):
value = klass() value = klass()
instantiated = 1 else:
if not instantiated:
try: try:
# Uh oh... we need to call the constructor with the initial value = apply(klass, initargs)
# arguments, but we also have to preserve the identity of
# the object, to keep recursive objects right.
v2 = apply(klass, initargs)
except TypeError, err: except TypeError, err:
raise TypeError, 'in constructor for %s: %s' % ( raise TypeError, 'in constructor for %s: %s' % (
klass.__name__, str(err)), sys.exc_info()[2] klass.__name__, str(err)), sys.exc_info()[2]
else:
for k, v in v2.__dict__.items():
setattr(value, k, v)
# Now set the object's attributes from the marshalled dictionary # Now set the object's attributes from the marshalled dictionary
for k, v in kw.items(): for k, v in kw.items():
...@@ -634,6 +625,14 @@ class _A: ...@@ -634,6 +625,14 @@ class _A:
class _B(object): class _B(object):
def __repr__(self): def __repr__(self):
return '<B instance>' return '<B instance>'
class _C(object):
def __init__(self, attr1, attr2=None):
self.attr1 = attr1
self.attr2 = attr2
def __getinitargs__(self):
return (self.attr1, )
def __repr__(self):
return '<C instance>'
def runtests(namespace_uri=None): def runtests(namespace_uri=None):
print "Testing XML marshalling..." print "Testing XML marshalling..."
...@@ -689,6 +688,22 @@ def runtests(namespace_uri=None): ...@@ -689,6 +688,22 @@ def runtests(namespace_uri=None):
</marshal:marshal>""") </marshal:marshal>""")
assert output == (1.0, 'abc', []) assert output == (1.0, 'abc', [])
c_instance = _C('value1', attr2='value2')
c_instance.attr3 = 'value3'
nested_instance = _C('somevalue', 'someother')
nested_instance.attr3 = "stillanother"
c_instance.nested_instance = nested_instance
c_marshalled = dumps(c_instance)
c_unmarshalled = loads(c_marshalled)
assert c_unmarshalled.attr3 == c_instance.attr3
assert c_unmarshalled.attr2 == c_instance.attr2
assert c_unmarshalled.attr1 == c_instance.attr1
assert c_unmarshalled.__class__ == _C
assert c_unmarshalled.nested_instance.__class__ == _C
assert c_unmarshalled.nested_instance.attr1 == nested_instance.attr1
assert c_unmarshalled.nested_instance.attr2 == nested_instance.attr2
assert c_unmarshalled.nested_instance.attr3 == nested_instance.attr3
if __name__ == '__main__': if __name__ == '__main__':
runtests() runtests()
runtests(namespace_uri='http://www.erp5.org/namespaces/marshaller') runtests(namespace_uri='http://www.erp5.org/namespaces/marshaller')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment