diff --git a/src/zeep/wsse/signature.py b/src/zeep/wsse/signature.py
index 47ab7fd4..3ff48929 100644
--- a/src/zeep/wsse/signature.py
+++ b/src/zeep/wsse/signature.py
@@ -53,6 +53,8 @@ def __init__(
password=None,
signature_method=None,
digest_method=None,
+ verify_response_signature=True,
+ response_cert_data=None,
):
check_xmlsec_import()
@@ -61,6 +63,8 @@ def __init__(
self.password = password
self.digest_method = digest_method
self.signature_method = signature_method
+ self.verify_response_signature = verify_response_signature
+ self.response_cert_data = response_cert_data
def apply(self, envelope, headers):
key = _make_sign_key(self.key_data, self.cert_data, self.password)
@@ -70,7 +74,11 @@ def apply(self, envelope, headers):
return envelope, headers
def verify(self, envelope):
- key = _make_verify_key(self.cert_data)
+ if not self.verify_response_signature:
+ return envelope
+
+ cert_data = self.response_cert_data if self.response_cert_data else self.cert_data
+ key = _make_verify_key(cert_data)
_verify_envelope_with_key(envelope, key)
return envelope
@@ -85,6 +93,8 @@ def __init__(
password=None,
signature_method=None,
digest_method=None,
+ verify_response_signature=True,
+ response_certfile=None,
):
super().__init__(
_read_file(key_file),
@@ -92,6 +102,8 @@ def __init__(
password,
signature_method,
digest_method,
+ verify_response_signature,
+ _read_file(response_certfile) if response_certfile else None
)
diff --git a/src/zeep/xsd/types/complex.py b/src/zeep/xsd/types/complex.py
index 4c69a9cd..65c39b95 100644
--- a/src/zeep/xsd/types/complex.py
+++ b/src/zeep/xsd/types/complex.py
@@ -447,6 +447,8 @@ def extend(self, base):
elif self._element or base_element:
element = self._element or base_element
+ elif isinstance(base, ComplexType):
+ element = None
else:
element = Element("_value_1", base)
diff --git a/tests/test_xsd_complex_types.py b/tests/test_xsd_complex_types.py
index 55430c91..6efb8945 100644
--- a/tests/test_xsd_complex_types.py
+++ b/tests/test_xsd_complex_types.py
@@ -422,3 +422,107 @@ def test_ignore_sequence_order():
response = elm.parse(node[0], schema)
assert response.Baz.id == 3
+
+
+def test_extension_with_attributes_preserves_values():
+ schema = xsd.Schema(
+ load_xml(
+ """
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """
+ )
+ )
+ schema.set_ns_prefix("tns", "http://tests.python-zeep.org/")
+
+ item_elm = schema.get_element("tns:item")
+ obj = item_elm(attr1=10, attr2="test")
+
+ assert obj.attr1 == 10
+ assert obj.attr2 == "test"
+
+ result = render_node(item_elm, obj)
+ expected = """
+
+
+
+ """
+ assert_nodes_equal(result, expected)
+
+ parsed = item_elm.parse(result[0], schema)
+ assert parsed.attr1 == 10
+ assert parsed.attr2 == "test"
+
+
+def test_extension_with_attributes_and_elements():
+ schema = xsd.Schema(
+ load_xml(
+ """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """
+ )
+ )
+ schema.set_ns_prefix("tns", "http://tests.python-zeep.org/")
+
+ container_elm = schema.get_element("tns:container")
+ extended_type = schema.get_type("tns:ExtendedType")
+
+ obj = container_elm(item=extended_type(attr1=10, attr2="test"))
+
+ assert obj.item.attr1 == 10
+ assert obj.item.attr2 == "test"
+
+ result = render_node(container_elm, obj)
+ expected = """
+
+
+
+
+
+ """
+ assert_nodes_equal(result, expected)
+
+ parsed = container_elm.parse(result[0], schema)
+ assert parsed.item.attr1 == 10
+ assert parsed.item.attr2 == "test"