Skip to content

Commit

Permalink
Emit warning when converting parent field to a list
Browse files Browse the repository at this point in the history
  • Loading branch information
tefra committed Dec 18, 2023
1 parent d9c6ada commit 9dcdce5
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def test_overrides(self):
def test_validate_override(self):
attr_a = AttrFactory.create()
attr_b = attr_a.clone()
attr_b.parent = ClassFactory.create()
target = ClassFactory.create()
target.attrs.append(attr_a)

Expand Down
8 changes: 8 additions & 0 deletions xsdata/codegen/handlers/validate_attributes_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from xsdata.codegen.models import Class
from xsdata.codegen.models import get_slug
from xsdata.codegen.utils import ClassUtils
from xsdata.logger import logger
from xsdata.utils import collections


Expand Down Expand Up @@ -53,6 +54,13 @@ def validate_override(cls, target: Class, attr: Attr, source_attr: Attr):
if attr.is_list and not source_attr.is_list:
# Hack much??? idk but Optional[str] can't override List[str]
source_attr.restrictions.max_occurs = sys.maxsize
assert source_attr.parent is not None
logger.warning(
"Converting parent field `%s::%s` to a list to match child class `%s`",
source_attr.parent.name,
source_attr.name,
target.name,
)

if (
attr.default == source_attr.default
Expand Down
5 changes: 4 additions & 1 deletion xsdata/codegen/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ def base_attrs(self, target: Class) -> List[Attr]:
assert base is not None

attrs.extend(self.base_attrs(base))
attrs.extend(base.attrs)

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

return attrs

Expand Down
19 changes: 10 additions & 9 deletions xsdata/codegen/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def clone(self) -> "Restrictions":

@classmethod
def from_element(cls, element: ElementBase) -> "Restrictions":
"""Static constructor from an xsd model."""
"""Static constructor from a xsd model."""
return cls(**element.get_restrictions())


Expand Down Expand Up @@ -193,7 +193,7 @@ def name(self) -> str:
return namespaces.local_name(self.qname)

def is_dependency(self, allow_circular: bool) -> bool:
"""Return true if attribute is not a forward/circular references and
"""Return true if attribute is not a forward/circular references, and
it's not a native python time."""

return not (
Expand Down Expand Up @@ -221,6 +221,7 @@ class Attr:
namespace: Optional[str] = field(default=None)
help: Optional[str] = field(default=None, compare=False)
restrictions: Restrictions = field(default_factory=Restrictions, compare=False)
parent: Optional["Class"] = field(default=None, compare=False)

def __post_init__(self):
self.local_name = self.name
Expand All @@ -231,13 +232,13 @@ def key(self) -> str:

@property
def is_attribute(self) -> bool:
"""Return whether this attribute is derived from an xs:attribute or
"""Return whether this attribute is derived from a xs:attribute or
xs:anyAttribute."""
return self.tag in (Tag.ATTRIBUTE, Tag.ANY_ATTRIBUTE)

@property
def is_enumeration(self) -> bool:
"""Return whether this attribute is derived from an xs:enumeration."""
"""Return whether this attribute is derived from a xs:enumeration."""
return self.tag == Tag.ENUMERATION

@property
Expand All @@ -252,7 +253,7 @@ def is_factory(self) -> bool:

@property
def is_group(self) -> bool:
"""Return whether this attribute is derived from an xs:group or
"""Return whether this attribute is derived from a xs:group or
xs:attributeGroup."""
return self.tag in (Tag.ATTRIBUTE_GROUP, Tag.GROUP)

Expand Down Expand Up @@ -283,7 +284,7 @@ def is_optional(self) -> bool:

@property
def is_suffix(self) -> bool:
"""Return whether this attribute is not derived from an xs element with
"""Return whether this attribute is not derived from a xs element with
mode suffix."""
return self.index == sys.maxsize

Expand Down Expand Up @@ -431,13 +432,13 @@ def has_help_attr(self) -> bool:

@property
def is_complex(self) -> bool:
"""Return whether this instance is derived from an xs:element or
"""Return whether this instance is derived from a xs:element or
xs:complexType."""
return self.tag in (Tag.ELEMENT, Tag.COMPLEX_TYPE)

@property
def is_element(self) -> bool:
"""Return whether this instance is derived from an non abstract
"""Return whether this instance is derived from a non abstract
xs:element."""
return self.tag == Tag.ELEMENT

Expand All @@ -456,7 +457,7 @@ class or a complex type without simple content."""

@property
def is_group(self) -> bool:
"""Return whether this attribute is derived from an xs:group or
"""Return whether this attribute is derived from a xs:group or
xs:attributeGroup."""
return self.tag in (Tag.ATTRIBUTE_GROUP, Tag.GROUP)

Expand Down

0 comments on commit 9dcdce5

Please sign in to comment.