Fixed a suds.xsd.sxbasic.SchemaObject resolve() invalid cached value bug.
When called with parameter nobuiltin=True on a node whose type is a builtin, the original implementation cached the builtin type as the result so a repeated resolve() call returned an incorrect value. Added related test case. Refactored the resolve() implementation into an external function dealing with result caching and in internal worker function doing the actual type resolution. Updated todo list.
This commit is contained in:
parent
0ae85957e5
commit
4a0b406cf5
16
TODO.txt
16
TODO.txt
|
@ -243,14 +243,16 @@ PRIORETIZED:
|
|||
(+) * Prevent possible endless resolve() loops due to resolve()
|
||||
(+) directly or indirectly returning the same TypedContent
|
||||
(+) instance.
|
||||
(+) * (Jurko) Clean up suds.xsd.sxbasic.TypedContent.resolve().
|
||||
(+) * Refactor to cache the final resolved type instead of a possibly only
|
||||
(+) partially resolved one when resolving without allowing resolving to
|
||||
(+) builtin types.
|
||||
(+) * Research.
|
||||
(+) * Prepare test.
|
||||
(+) * Update code.
|
||||
|
||||
* (Jurko) Clean up suds.xsd.sxbasic.TypedContent.resolve().
|
||||
* Refactor to cache the final resolved type instead of a possibly only
|
||||
partially resolved one when resolving without allowing resolving to
|
||||
builtin types.
|
||||
* Research.
|
||||
* Prepare test.
|
||||
* Update code.
|
||||
* (Jurko) Check and remove the splitPrefix import from suds.xsd.sxbasic and
|
||||
other modules if it is no longer needed.
|
||||
|
||||
|
||||
NON PRIORETIZED:
|
||||
|
|
|
@ -61,17 +61,30 @@ class TypedContent(Content):
|
|||
@return: The resolved (true) type.
|
||||
@rtype: L{SchemaObject}
|
||||
"""
|
||||
# Implementation note:
|
||||
# Note that there is no need for a recursive implementation here
|
||||
# since a node can reference an external type node but there is no way
|
||||
# using WSDL to then make that type node actually be a reference to a
|
||||
# different type node.
|
||||
qref = self.qref()
|
||||
if qref is None:
|
||||
return self
|
||||
cached = self.resolved_cache.get(nobuiltin)
|
||||
if cached is not None:
|
||||
return cached
|
||||
resolved = self.__resolve_type(nobuiltin)
|
||||
self.resolved_cache[nobuiltin] = resolved
|
||||
return resolved
|
||||
|
||||
def __resolve_type(self, nobuiltin=False):
|
||||
"""
|
||||
Private resolve() worker without any result caching.
|
||||
@param nobuiltin: Flag indicating whether resolving to XSD builtin
|
||||
types should not be allowed.
|
||||
@return: The resolved (true) type.
|
||||
@rtype: L{SchemaObject}
|
||||
|
||||
Implementation note:
|
||||
Note that there is no need for a recursive implementation here since
|
||||
a node can reference an external type node but there is no way using
|
||||
WSDL to then make that type node actually be a reference to a different
|
||||
type node.
|
||||
"""
|
||||
qref = self.qref()
|
||||
if qref is None:
|
||||
return self
|
||||
query = TypeQuery(qref)
|
||||
query.history = [self]
|
||||
log.debug('%s, resolving: %s\n using:%s', self.id, qref, query)
|
||||
|
@ -79,11 +92,9 @@ class TypedContent(Content):
|
|||
if resolved is None:
|
||||
log.debug(self.schema)
|
||||
raise TypeNotFound(qref)
|
||||
self.resolved_cache[nobuiltin] = resolved
|
||||
result = resolved
|
||||
if resolved.builtin() and nobuiltin:
|
||||
result = self
|
||||
return result
|
||||
return self
|
||||
return resolved
|
||||
|
||||
def qref(self):
|
||||
"""
|
||||
|
|
|
@ -1437,11 +1437,61 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
# Resolving builtin type nodes.
|
||||
assert typo_u1.resolve().__class__ is suds.xsd.sxbuiltin.XString
|
||||
assert typo_u1.resolve(nobuiltin=False).__class__ is \
|
||||
suds.xsd.sxbuiltin.XString
|
||||
assert typo_u1.resolve(nobuiltin=True) is typo_u1
|
||||
assert elemento_x2.resolve(nobuiltin=True) is typo
|
||||
assert elemento_x3.resolve(nobuiltin=True) is elemento_x3
|
||||
|
||||
|
||||
def test_schema_node_resolve__nobuiltin_caching():
|
||||
client = _client_from_wsdl(
|
||||
"""<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns:ns="my-namespace"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
||||
<wsdl:types>
|
||||
<xsd:schema targetNamespace="my-namespace"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<xsd:element name="Elemento1" type="xsd:string" />
|
||||
<xsd:element name="Elemento2" type="xsd:string" />
|
||||
<xsd:element name="Elemento3" type="xsd:string" />
|
||||
<xsd:element name="Elemento4" type="xsd:string" />
|
||||
</xsd:schema>
|
||||
</wsdl:types>
|
||||
</wsdl:definitions>
|
||||
""")
|
||||
schema = client.wsdl.schema
|
||||
|
||||
# Collect references to the test schema element nodes.
|
||||
assert len(schema.elements) == 4
|
||||
e1 = schema.elements["Elemento1", "my-namespace"]
|
||||
e2 = schema.elements["Elemento2", "my-namespace"]
|
||||
e3 = schema.elements["Elemento3", "my-namespace"]
|
||||
e4 = schema.elements["Elemento4", "my-namespace"]
|
||||
|
||||
# Repeating the same resolve() call twice makes sure that the first call
|
||||
# does not cache an incorrect value, thus causing the second call to return
|
||||
# an incorrect result.
|
||||
|
||||
assert e1.resolve().__class__ is suds.xsd.sxbuiltin.XString
|
||||
assert e1.resolve().__class__ is suds.xsd.sxbuiltin.XString
|
||||
|
||||
assert e2.resolve(nobuiltin=True) is e2
|
||||
assert e2.resolve(nobuiltin=True) is e2
|
||||
|
||||
assert e3.resolve().__class__ is suds.xsd.sxbuiltin.XString
|
||||
assert e3.resolve(nobuiltin=True) is e3
|
||||
assert e3.resolve(nobuiltin=True) is e3
|
||||
|
||||
assert e4.resolve(nobuiltin=True) is e4
|
||||
assert e4.resolve().__class__ is suds.xsd.sxbuiltin.XString
|
||||
assert e4.resolve().__class__ is suds.xsd.sxbuiltin.XString
|
||||
|
||||
|
||||
def test_schema_node_resolve__invalid_type():
|
||||
client = _client_from_wsdl(
|
||||
"""<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
|
Loading…
Reference in New Issue