Issue 1070046: xmlrpclib - marshalling new-style classes. (original) (raw)
This bug is linked to bug 469972. Tested with python 2.3.4
Bug desciption: Using xmlrpclib today (version 1.0.1) we can marshall old-style classes, but new style classes cannot be marshalled. E.g. import xmlrpclib class NewObject(object): def init(self): self.mytype = 'new'
class OldObject: def init(self): self.mytype = 'old'
print xmlrpclib.dumps((OldObject(),))
result OK, marshalled as a struct
print xmlrpclib.dumps((NewObject(),))
TypeError: cannot marshal <class '__main__.NewObject'>
objects
So the module doesn't behave in the same way with new-style classes.
Bug analysis: The problem is that xmlrpclib try to guess how to marshall an object using the type() method (see line 612), but old-style classes have type 'InstanceType' whereas new-style classes are of type 'ObjectType'.
Furthermore as described in bug 469972 we don't know how to marshal class sub-classing builtin types (string, int, etc)
Patch proposed: The problem is in the _dump method,. We have this code : try: f = self.dispatch[type(value)] except KeyError:
here goes the patch !
Currently with new-style classes we have a KeyError exception since the ObjectType is not in the key list of self.dispatch. As all objects(string , dict, user defined classes...) in Python now have type 'ObjectType' we cannot just add a line: dispatch[ObjectType] = dump_instance
In the KeyError, the patch checks if the object has a dictionnary. Because in this case it is probably a good candidate for being marshalled as a struct. And then the patch checks that the object doesn't inherit from a basic type (int, string etc.. : in fact all the types that are 'normally' marshalled). And if these 2 conditions are OK, this object is marshalled like old-style classes.
The proposed patch doesn't change xmlrpclib behaviour for all basic types, and old-style classes since only the 'except KeyError' was changed.
Gabriel Pastor