The problem: I have a Python class implemented as a subclass of the built-in dictionary type:
class Foo(dict): ... code here ...
I want to send an instance of this class across an xml-rpc link:
f = Foo() ... do stuff with f ... import xmlrpclib server = xmlrpclib.ServerProxy('...') server.foo(f)
It doesn’t work:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python27\lib\xmlrpclib.py", line 1224, in __call__ return self.__send(self.__name, args) File "C:\Python27\lib\xmlrpclib.py", line 1569, in __request allow_none=self.__allow_none) File "C:\Python27\lib\xmlrpclib.py", line 1085, in dumps data = m.dumps(params) File "C:\Python27\lib\xmlrpclib.py", line 632, in dumps dump(v, write) File "C:\Python27\lib\xmlrpclib.py", line 652, in __dump raise TypeError, "cannot marshal %s objects" % type(value) TypeError: cannot marshal <class '__main__.Foo'> objects
This is because xmlrpclib checks specifically for the built-in dictionary type – not user-defined types that behave like dictionaries, not even user-defined subclasses of dictionaries – and throws a TypeError exception if it doesn’t get one. The justification for this rather unfortunate behavior is that an xml-rpc link must be symmetrical: the type that comes out must be the type that went in.
So it’s my job to massage my data into one of the few supported formats before handing it to xmlrpclib. Fine, I can do that. But how do I coerce my subclass back to a simple dictionary, so xmlrpclib will marshal it without throwing an exception? I don’t want to convert it, I don’t want to copy it; that would be slow. I just want to strip off the subclass, leaving the dictionary behind.
Turns out there’s no way to do that, either. Python doesn’t do <reinterpret_cast> or anything like it.