Skip to content

Commit

Permalink
fix: handle abstract types
Browse files Browse the repository at this point in the history
This makes some assumptions which need testing, but currently I do not have
an appropriate test environment to test against.  Making available to see if
someone else can test before I get access to an appropriate environment.
  • Loading branch information
nigelm committed Apr 9, 2022
1 parent e421069 commit 84abaa2
Show file tree
Hide file tree
Showing 8 changed files with 923 additions and 145 deletions.
51 changes: 39 additions & 12 deletions broadworks_ocip/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ElementInfo:
is_required: bool = attr.ib(default=False)
is_array: bool = attr.ib(default=False)
is_table: bool = attr.ib(default=False)
is_abstract: bool = attr.ib(default=False)


class OCIType:
Expand Down Expand Up @@ -135,6 +136,11 @@ def type_(self):
"""Return the typename of the class"""
return self.__class__.__name__

@classmethod
def class_to_property_(self, name):
"""Map a XML class name to the associated property"""
return name[0].lower() + name[1:]

def post_xml_decode_(self):
"""
Carry out any operations after the XML decode
Expand Down Expand Up @@ -222,11 +228,19 @@ def etree_sub_element_(
col_item = etree.SubElement(row_item, "col")
col_item.text = col
elif sub_element.is_complex:
elem = etree.SubElement(
element,
sub_element.xmlname,
nsmap=self._default_nsmap(),
)
if sub_element.is_abstract:
elem_name = self.class_to_property_(value.type_)
elem = etree.SubElement(
element,
elem_name,
nsmap=self._default_nsmap(),
)
else:
elem = etree.SubElement(
element,
sub_element.xmlname,
nsmap=self._default_nsmap(),
)
value.etree_sub_components_(elem)
else:
elem = etree.SubElement(
Expand Down Expand Up @@ -354,13 +368,26 @@ def build_from_etree_(cls, element: etree._Element, extras: Dict[str, Any] = {})
result.append(cls.build_from_node_(elem=elem, node=node))
initialiser[elem.name] = result
else:
node = element.find(elem.xmlname)
if node is not None:
initialiser[elem.name] = cls.build_from_node_(elem=elem, node=node)
# else...
# I am inclined to thow an error here - at least after checking if
# the thing is require, but the class builder should do that so lets
# let it do its thing
if elem.is_abstract:
for subclass in elem.type.__subclasses__():
elem_name = cls.class_to_property_(subclass.__name__)
node = element.find(elem_name)
if node is not None:
initialiser[elem.name] = subclass.build_from_node_(
elem=elem,
node=node,
)
else:
node = element.find(elem.xmlname)
if node is not None:
initialiser[elem.name] = cls.build_from_node_(
elem=elem,
node=node,
)
# else...
# I am inclined to thow an error here - at least after checking if
# the thing is require, but the class builder should do that so lets
# let it do its thing
# now have a dict with all the bits in it.
# use that to build a new object
return cls(**initialiser)
Expand Down
Loading

0 comments on commit 84abaa2

Please sign in to comment.