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("""\