Skip to content

Commit

Permalink
Merge pull request #998 from tefra/sdmx-ml-suite
Browse files Browse the repository at this point in the history
fit: Resolve prohibited attrs override issues
  • Loading branch information
tefra authored Mar 25, 2024
2 parents ff01d9b + ffe2bd1 commit 96d2085
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 17 deletions.
20 changes: 19 additions & 1 deletion tests/codegen/handlers/test_validate_attributes_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,29 @@ def test_validate_override(self):
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(sys.maxsize, attr_b.restrictions.max_occurs)

# Parent is list, source is not
target.attrs = [attr_a]
attr_a.restrictions.min_occurs = 0
attr_a.restrictions.max_occurs = 1
attr_b.restrictions.min_occurs = 0
attr_b.restrictions.max_occurs = 2
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(2, attr_b.restrictions.max_occurs)

# Source is list, parent is prohibited
target.attrs = [attr_a]
attr_a.restrictions.min_occurs = None
attr_a.restrictions.max_occurs = 10
attr_b.restrictions.min_occurs = 0
attr_b.restrictions.max_occurs = 0
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(0, attr_b.restrictions.max_occurs)
self.assertIn(attr_a, target.attrs)

# Parent is any type, source isn't, skip
attr_a = AttrFactory.native(DataType.STRING)
attr_b = AttrFactory.native(DataType.ANY_SIMPLE_TYPE)
target = ClassFactory.create(attrs=[attr_a])

self.processor.validate_override(target, attr_a.clone(), attr_b)
self.assertEqual(attr_a, target.attrs[0])

Expand Down
46 changes: 32 additions & 14 deletions xsdata/codegen/handlers/validate_attributes_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,27 +127,45 @@ def validate_override(cls, target: Class, child_attr: Attr, parent_attr: Attr):
if parent_attr.is_any_type and not child_attr.is_any_type:
return

if child_attr.is_list and not parent_attr.is_list:
if (
child_attr.is_list
and not parent_attr.is_list
and not parent_attr.is_prohibited
) or (
not child_attr.is_list
and not child_attr.is_prohibited
and parent_attr.is_list
):
# Hack much??? idk but Optional[str] can't override List[str]
parent_attr.restrictions.max_occurs = sys.maxsize
msg = "Converting {} field `{}::{}` to a list to match {} class `{}`"
assert parent_attr.parent is not None
logger.warning(
"Converting parent field `%s::%s` to a list to match child class `%s`",
parent_attr.parent,
parent_attr.name,
target.name,
)

if child_attr.is_list:
parent_attr.restrictions.max_occurs = sys.maxsize
log_message = msg.format(
"parent",
parent_attr.parent,
parent_attr.name,
"child",
target.qname,
)
else:
child_attr.restrictions.max_occurs = parent_attr.restrictions.max_occurs
log_message = msg.format(
"child",
target.name,
child_attr.name,
"parent",
parent_attr.parent,
)
logger.warning(log_message)

if (
child_attr.default == parent_attr.default
and _bool_eq(child_attr.fixed, parent_attr.fixed)
and _bool_eq(child_attr.mixed, parent_attr.mixed)
and _bool_eq(
child_attr.restrictions.tokens, parent_attr.restrictions.tokens
)
and _bool_eq(
child_attr.restrictions.nillable, parent_attr.restrictions.nillable
)
and _bool_eq(child_attr.is_tokens, parent_attr.is_tokens)
and _bool_eq(child_attr.is_nillable, parent_attr.is_nillable)
and _bool_eq(child_attr.is_prohibited, parent_attr.is_prohibited)
and _bool_eq(child_attr.is_optional, parent_attr.is_optional)
):
Expand Down
4 changes: 2 additions & 2 deletions xsdata/codegen/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ def base_attrs(self, target: Class) -> List[Attr]:

assert base is not None

attrs.extend(self.base_attrs(base))

for attr in base.attrs:
attr.parent = base.qname
attrs.append(attr)

attrs.extend(self.base_attrs(base))

return attrs

@abc.abstractmethod
Expand Down

0 comments on commit 96d2085

Please sign in to comment.