From 313185c9b47f97aec9d3370de9373115dd80e25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurko=20Gospodneti=C4=87?= Date: Mon, 27 Jul 2015 11:04:48 +0200 Subject: [PATCH] marshal passed empty object optional params as empty tags 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. This seems correct as passing an empty object and not passing an object are two distinct use-cases and there are web-services out there (e.g. `https://ads.google.com/apis/ads/publisher/v201502/LineItemService?wsdl`) that do differentiate between the two. Fixes issue filed on BitBucket under: `https://bitbucket.org/jurko/suds/issues/81/suds-should-support-an-empty-object` Kudos to Nicholas Chen (nicholaschen at BitBucket) & Mark Saniscalchi (msaniscalchi at BitBucket) for reporting the issue and preparing the initial fix. --- README.rst | 14 ++++++++ suds/mx/appender.py | 3 -- tests/test_request_construction.py | 51 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) 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("""\