#303 issubclass modificaiton to work with wsdl2py

v2.1
open
nobody
zsi (169)
5
2012-10-26
2012-10-26
RichardGalka
No

Python 2.7.3
ZSI.Version = (2.1.0)

Resulting python classes due to running wsdl2py on a wsdl creates a scenario where utilizing these throws
TypeError: Substitute Type (%s, %s) is not derived from %s.

It appears the issue is caused by schema.py issubclass(subclass, pyclass) call and the way wsdl2py creates it's classes.

When dealing with an ArrayOfXXX superclass the below is identified:

>>> pyclass
<class 'Service_types.ArrayOfAccessRight_Def'>
>>> pyclass.__bases__
(<class 'Service_types.Array_Def'>, <class 'ZSI.schema.TypeDefinition'>)
>>> subclass
<class 'Service_types.Array_Def'>
>>> issubclass(subclass, pyclass)
False

This appears to be because Service_types.ArrayOfAccessRight_Def modifies it's class' __bases__ during runtime:
[From file generated by wsdl2py]
if ns2.Array_Def not in ns1.ArrayOfAccessRight_Def.__bases__:
bases = list(ns1.ArrayOfAccessRight_Def.__bases__)
bases.insert(0, ns2.Array_Def)
ns1.ArrayOfAccessRight_Def.__bases__ = tuple(bases)

So, although the class [Array_Def] is in [ArrayOfAccessRight_Def] base, the python 2.7 issubclass(x,y) still reports failure.

To get this working in our environment the following patch was used (I'm not sure what other ramifications this may cause):

--- schema.py 2012-10-26 14:51:36.000000000 -0500
+++ schema.py.new 2012-10-26 14:27:57.000000000 -0500
@@ -289,7 +289,7 @@ class TypeDefinition:
'No registered xsi:type=(%s, %s), substitute for xsi:type=(%s, %s)' %
(uri, typeName, self.type[0], self.type[1]), ps.Backtrace(elt))

- if not issubclass(subclass, pyclass) and subclass(None) and not issubclass(subclass, pyclass):
+ if not subclass in pyclass.__bases__ and subclass(None) and not issubclass(subclass, pyclass):
raise TypeError(
'Substitute Type (%s, %s) is not derived from %s' %
(self.type[0], self.type[1], pyclass), ps.Backtrace(elt))

[Relevant wsdl file section]

<complexType name="ArrayOfAccessRight">
<complexContent>
<restriction base="SOAP-ENC:Array">
<sequence>
<element name="item" type="fs:AccessRight" minOccurs="0" maxOccurs="unbounded" nillable="false"/>
</sequence>
<attribute ref="SOAP-ENC:arrayType" WSDL:arrayType="fs:AccessRight[]"/>
</restriction>
</complexContent>
</complexType>

Please let me know if more information / more complete example is required.

Discussion