From a5fd4ddbe24f3eeb4d8ad012dc53db388002d701 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 26 Nov 2021 12:49:31 +0200 Subject: [PATCH] AttributeTypeHandler: filter abstract elements from class attrs Notes: The schema is invalid if an element ref points to an abstract element, the only acceptable case is when abstract elements are used like placeholders for substitutions groups. --- tests/codegen/handlers/test_attribute_type.py | 16 ++++++++++++++++ xsdata/codegen/handlers/attribute_type.py | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/tests/codegen/handlers/test_attribute_type.py b/tests/codegen/handlers/test_attribute_type.py index 5cde1d9aa..b109dcca5 100644 --- a/tests/codegen/handlers/test_attribute_type.py +++ b/tests/codegen/handlers/test_attribute_type.py @@ -189,6 +189,22 @@ def test_process_dependency_type_with_complex_type( self.processor.process_dependency_type(target, attr, attr_type) self.assertTrue(attr.restrictions.nillable) + @mock.patch.object(AttributeTypeHandler, "find_dependency") + def test_process_dependency_type_with_abstract_type_type( + self, mock_find_dependency + ): + complex_type = ClassFactory.create(tag=Tag.ELEMENT, abstract=True) + mock_find_dependency.return_value = complex_type + + attr = AttrFactory.create() + attr_type = attr.types[0] + target = ClassFactory.create() + target.attrs.append(attr) + + self.assertEqual(1, len(target.attrs)) + self.processor.process_dependency_type(target, attr, attr_type) + self.assertEqual(0, len(target.attrs)) + @mock.patch.object(AttributeTypeHandler, "update_restrictions") @mock.patch.object(AttributeTypeHandler, "copy_attribute_properties") def test_process_inner_type_with_simple_type( diff --git a/xsdata/codegen/handlers/attribute_type.py b/xsdata/codegen/handlers/attribute_type.py index ec4c0b11d..e89b45ce4 100644 --- a/xsdata/codegen/handlers/attribute_type.py +++ b/xsdata/codegen/handlers/attribute_type.py @@ -140,6 +140,10 @@ def process_dependency_type(self, target: Class, attr: Attr, attr_type: AttrType x.restrictions.format for x in source.attrs if x.restrictions.format ) attr_type.reference = id(source) + elif source.is_element and source.abstract: + # Substitution groups with abstract elements are used like + # placeholders and shouldn't be added as standalone fields. + target.attrs.remove(attr) else: if source.nillable: attr.restrictions.nillable = True