From 1f4c42393544037b02d45831fb00d03ed8e19f00 Mon Sep 17 00:00:00 2001 From: Chris Tsou Date: Mon, 9 Dec 2024 17:32:11 +0200 Subject: [PATCH] Fix: Priorities when selecting source attr type (#1107) --- .../handlers/test_process_attributes_types.py | 15 +++++++++------ .../codegen/handlers/process_attributes_types.py | 15 ++++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/codegen/handlers/test_process_attributes_types.py b/tests/codegen/handlers/test_process_attributes_types.py index b7b961784..e207f2714 100644 --- a/tests/codegen/handlers/test_process_attributes_types.py +++ b/tests/codegen/handlers/test_process_attributes_types.py @@ -344,25 +344,28 @@ def test_find_dependency(self): complex_type = ClassFactory.create(qname="a", tag=Tag.COMPLEX_TYPE) simple_type = ClassFactory.create(qname="a", tag=Tag.SIMPLE_TYPE) - actual = self.processor.find_dependency(attr_type, Tag.ELEMENT) + actual = self.processor.find_dependency(element, attr_type, Tag.ELEMENT) self.assertIsNone(actual) self.processor.container.add(simple_type) - actual = self.processor.find_dependency(attr_type, Tag.ELEMENT) + actual = self.processor.find_dependency(element, attr_type, Tag.ELEMENT) self.assertEqual(simple_type, actual) self.processor.container.add(complex_type) - actual = self.processor.find_dependency(attr_type, Tag.ELEMENT) + actual = self.processor.find_dependency(element, attr_type, Tag.ELEMENT) self.assertEqual(complex_type, actual) self.processor.container.add(element) - actual = self.processor.find_dependency(attr_type, Tag.ELEMENT) + actual = self.processor.find_dependency(complex_type, attr_type, Tag.ELEMENT) self.assertEqual(element, actual) - actual = self.processor.find_dependency(attr_type, Tag.SIMPLE_TYPE) + actual = self.processor.find_dependency(element, attr_type, Tag.ELEMENT) + self.assertEqual(complex_type, actual) + + actual = self.processor.find_dependency(element, attr_type, Tag.SIMPLE_TYPE) self.assertEqual(simple_type, actual) - actual = self.processor.find_dependency(attr_type, Tag.EXTENSION) + actual = self.processor.find_dependency(element, attr_type, Tag.EXTENSION) self.assertEqual(simple_type, actual) def test_update_restrictions(self): diff --git a/xsdata/codegen/handlers/process_attributes_types.py b/xsdata/codegen/handlers/process_attributes_types.py index adba61e1f..2475be572 100644 --- a/xsdata/codegen/handlers/process_attributes_types.py +++ b/xsdata/codegen/handlers/process_attributes_types.py @@ -113,16 +113,19 @@ def process_native_type(cls, attr: Attr, attr_type: AttrType): if attr.restrictions.pattern: cls.reset_attribute_type(attr_type) - def find_dependency(self, attr_type: AttrType, tag: str) -> Optional[Class]: + def find_dependency( + self, target: Class, attr_type: AttrType, tag: str + ) -> Optional[Class]: """Find the source type from the attr type and tag. Avoid conflicts by selecting any matching type by qname and preferably: - 1. Match the candidate object tag - 2. Match element again complexType + 1. Match element again complexType with no self reference + 2. Match the candidate object tag 3. Match non element and complexType 4. Anything Args: + target: The target class instance attr_type: The attr type instance tag: The xml tag name, e.g. Element, Attribute, ComplexType @@ -130,8 +133,10 @@ def find_dependency(self, attr_type: AttrType, tag: str) -> Optional[Class]: The source class or None if no match is found """ conditions = ( + lambda obj: tag == Tag.ELEMENT + and obj.tag == Tag.COMPLEX_TYPE + and obj is not target, lambda obj: obj.tag == tag, - lambda obj: tag == Tag.ELEMENT and obj.tag == Tag.COMPLEX_TYPE, lambda obj: not obj.is_complex_type, lambda x: True, ) @@ -184,7 +189,7 @@ def process_dependency_type(self, target: Class, attr: Attr, attr_type: AttrType attr: The attr instance attr_type: The attr type instance """ - source = self.find_dependency(attr_type, attr.tag) + source = self.find_dependency(target, attr_type, attr.tag) if not source: logger.warning("Reset absent type: %s", attr_type.name) self.reset_attribute_type(attr_type)