diff --git a/README.rst b/README.rst index face5bd..776fc4d 100644 --- a/README.rst +++ b/README.rst @@ -177,6 +177,20 @@ version 0.7 (development) convert any encountered dictionaries to ``suds.sudsobject.Object`` instances and report an error in case a corresponding XSD type can not be found. +* Now marshalling passed empty object optional params as empty SOAP request XML + elements. + + * Before, passing an empty suds object as an optional parameter value was + treated the same as not passing that parameter's value or passing it + ``None`` - the value would not get marshalled into the constructed SOAP + request at all. + * Now, user can still not have the value marshalled by passing nothing or + ``None``, but passing an empty object will get marshalled as an actual SOAP + request XML element. + * Kudos to Nicholas Chen (nicholaschen at BitBucket) & Mark Saniscalchi + (msaniscalchi at BitBucket) for reporting the issue and preparing the + initial fix. + * Made ``suds`` no longer eat up, log & ignore exceptions raised from registered user plugins (detected & reported by Ezequiel Ruiz & Bouke Haarsma, patch & test case contributed by Bouke Haarsma). diff --git a/suds/mx/appender.py b/suds/mx/appender.py index 6ae1481..3736441 100644 --- a/suds/mx/appender.py +++ b/suds/mx/appender.py @@ -20,7 +20,6 @@ Provides appender classes for I{marshalling}. from suds import * from suds.mx import * -from suds.sudsobject import footprint from suds.sudsobject import Object, Property from suds.sax.element import Element from suds.sax.text import Text @@ -219,8 +218,6 @@ class ObjectAppender(Appender): def append(self, parent, content): object = content.value - if self.optional(content) and footprint(object) == 0: - return child = self.node(content) parent.append(child) for item in object: diff --git a/tests/test_request_construction.py b/tests/test_request_construction.py index 7d8e42f..52048cd 100644 --- a/tests/test_request_construction.py +++ b/tests/test_request_construction.py @@ -795,6 +795,57 @@ def test_optional_parameter_handling(): """ % (xsd_target_namespace,)) +def test_optional_parameter_with_empty_object_value(): + """Missing optional parameters should not get passed at all.""" + xsd_target_namespace = "I'm a cute little swamp gorilla monster!" + wsdl = testutils.wsdl("""\ + + + + + + + """, input="Wrapper", operation_name="f", + xsd_target_namespace=xsd_target_namespace) + client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True) + service = client.service + + # Base line: nothing passed --> nothing marshalled. + _assert_request_content(service.f(), """\ + + +
+ + + +""" % (xsd_target_namespace,)) + + # Passing a empty object as an empty dictionary. + _assert_request_content(service.f({}), """\ + + +
+ + + + + +""" % (xsd_target_namespace,)) + + # Passing a empty explicitly constructed `suds.sudsobject.Object`. + empty_object = client.factory.create("my_xsd:Wrapper") + _assert_request_content(service.f(empty_object), """\ + + +
+ + + + + +""" % (xsd_target_namespace,)) + + def test_SOAP_headers(): """Rudimentary 'soapheaders' option usage test.""" wsdl = suds.byte_str("""\