Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Priorities when selecting source attr type #1107

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions tests/codegen/handlers/test_process_attributes_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
15 changes: 10 additions & 5 deletions xsdata/codegen/handlers/process_attributes_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,25 +113,30 @@ 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

Returns:
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,
)
Expand Down Expand Up @@ -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)
Expand Down
Loading