diff --git a/basyx/aas/adapter/xml/xml_deserialization.py b/basyx/aas/adapter/xml/xml_deserialization.py index be66c30c7..8e698cf49 100644 --- a/basyx/aas/adapter/xml/xml_deserialization.py +++ b/basyx/aas/adapter/xml/xml_deserialization.py @@ -42,7 +42,7 @@ """ from ... import model -from lxml import etree # type: ignore +from lxml import etree import logging import base64 import enum @@ -77,7 +77,7 @@ def _str_to_bool(string: str) -> bool: return string == "true" -def _tag_replace_namespace(tag: str, nsmap: Dict[str, str]) -> str: +def _tag_replace_namespace(tag: str, nsmap: Dict[Optional[str], str]) -> str: """ Attempts to replace the namespace in front of a tag with the prefix used in the xml document. @@ -92,7 +92,7 @@ def _tag_replace_namespace(tag: str, nsmap: Dict[str, str]) -> str: return tag -def _element_pretty_identifier(element: etree.Element) -> str: +def _element_pretty_identifier(element: etree._Element) -> str: """ Returns a pretty element identifier for a given XML element. @@ -129,7 +129,7 @@ def _exception_to_str(exception: BaseException) -> str: return string[1:-1] if isinstance(exception, KeyError) else string -def _get_child_mandatory(parent: etree.Element, child_tag: str) -> etree.Element: +def _get_child_mandatory(parent: etree._Element, child_tag: str) -> etree._Element: """ A helper function for getting a mandatory child element. @@ -145,7 +145,7 @@ def _get_child_mandatory(parent: etree.Element, child_tag: str) -> etree.Element return child -def _get_all_children_expect_tag(parent: etree.Element, expected_tag: str, failsafe: bool) -> Iterable[etree.Element]: +def _get_all_children_expect_tag(parent: etree._Element, expected_tag: str, failsafe: bool) -> Iterable[etree._Element]: """ Iterates over all children, matching the tag. @@ -168,7 +168,7 @@ def _get_all_children_expect_tag(parent: etree.Element, expected_tag: str, fails yield child -def _get_attrib_mandatory(element: etree.Element, attrib: str) -> str: +def _get_attrib_mandatory(element: etree._Element, attrib: str) -> str: """ A helper function for getting a mandatory attribute of an element. @@ -179,10 +179,10 @@ def _get_attrib_mandatory(element: etree.Element, attrib: str) -> str: """ if attrib not in element.attrib: raise KeyError(f"{_element_pretty_identifier(element)} has no attribute with name {attrib}!") - return element.attrib[attrib] + return element.attrib[attrib] # type: ignore[return-value] -def _get_attrib_mandatory_mapped(element: etree.Element, attrib: str, dct: Dict[str, T]) -> T: +def _get_attrib_mandatory_mapped(element: etree._Element, attrib: str, dct: Dict[str, T]) -> T: """ A helper function for getting a mapped mandatory attribute of an xml element. @@ -203,7 +203,7 @@ def _get_attrib_mandatory_mapped(element: etree.Element, attrib: str, dct: Dict[ return dct[attrib_value] -def _get_text_or_none(element: Optional[etree.Element]) -> Optional[str]: +def _get_text_or_none(element: Optional[etree._Element]) -> Optional[str]: """ A helper function for getting the text of an element, when it's not clear whether the element exists or not. @@ -219,7 +219,7 @@ def _get_text_or_none(element: Optional[etree.Element]) -> Optional[str]: return element.text if element is not None else None -def _get_text_mapped_or_none(element: Optional[etree.Element], dct: Dict[str, T]) -> Optional[T]: +def _get_text_mapped_or_none(element: Optional[etree._Element], dct: Dict[str, T]) -> Optional[T]: """ Returns dct[element.text] or None, if the element is None, has no text or the text is not in dct. @@ -233,7 +233,7 @@ def _get_text_mapped_or_none(element: Optional[etree.Element], dct: Dict[str, T] return dct[text] -def _get_text_mandatory(element: etree.Element) -> str: +def _get_text_mandatory(element: etree._Element) -> str: """ A helper function for getting the mandatory text of an element. @@ -247,7 +247,7 @@ def _get_text_mandatory(element: etree.Element) -> str: return text -def _get_text_mandatory_mapped(element: etree.Element, dct: Dict[str, T]) -> T: +def _get_text_mandatory_mapped(element: etree._Element, dct: Dict[str, T]) -> T: """ A helper function for getting the mapped mandatory text of an element. @@ -266,7 +266,7 @@ def _get_text_mandatory_mapped(element: etree.Element, dct: Dict[str, T]) -> T: return dct[text] -def _failsafe_construct(element: Optional[etree.Element], constructor: Callable[..., T], failsafe: bool, +def _failsafe_construct(element: Optional[etree._Element], constructor: Callable[..., T], failsafe: bool, **kwargs: Any) -> Optional[T]: """ A wrapper function that is used to handle exceptions raised in constructor functions. @@ -302,7 +302,7 @@ def _failsafe_construct(element: Optional[etree.Element], constructor: Callable[ return None -def _failsafe_construct_mandatory(element: etree.Element, constructor: Callable[..., T], **kwargs: Any) -> T: +def _failsafe_construct_mandatory(element: etree._Element, constructor: Callable[..., T], **kwargs: Any) -> T: """ _failsafe_construct() but not failsafe and it returns T instead of Optional[T] @@ -320,7 +320,7 @@ def _failsafe_construct_mandatory(element: etree.Element, constructor: Callable[ return constructed -def _failsafe_construct_multiple(elements: Iterable[etree.Element], constructor: Callable[..., T], failsafe: bool, +def _failsafe_construct_multiple(elements: Iterable[etree._Element], constructor: Callable[..., T], failsafe: bool, **kwargs: Any) -> Iterable[T]: """ A generator function that applies _failsafe_construct() to multiple elements. @@ -339,7 +339,7 @@ def _failsafe_construct_multiple(elements: Iterable[etree.Element], constructor: yield parsed -def _child_construct_mandatory(parent: etree.Element, child_tag: str, constructor: Callable[..., T], **kwargs: Any) \ +def _child_construct_mandatory(parent: etree._Element, child_tag: str, constructor: Callable[..., T], **kwargs: Any) \ -> T: """ Shorthand for _failsafe_construct_mandatory() in combination with _get_child_mandatory(). @@ -353,7 +353,7 @@ def _child_construct_mandatory(parent: etree.Element, child_tag: str, constructo return _failsafe_construct_mandatory(_get_child_mandatory(parent, child_tag), constructor, **kwargs) -def _child_construct_multiple(parent: etree.Element, expected_tag: str, constructor: Callable[..., T], +def _child_construct_multiple(parent: etree._Element, expected_tag: str, constructor: Callable[..., T], failsafe: bool, **kwargs: Any) -> Iterable[T]: """ Shorthand for _failsafe_construct_multiple() in combination with _get_child_multiple(). @@ -370,7 +370,7 @@ def _child_construct_multiple(parent: etree.Element, expected_tag: str, construc failsafe, **kwargs) -def _child_text_mandatory(parent: etree.Element, child_tag: str) -> str: +def _child_text_mandatory(parent: etree._Element, child_tag: str) -> str: """ Shorthand for _get_text_mandatory() in combination with _get_child_mandatory(). @@ -381,7 +381,7 @@ def _child_text_mandatory(parent: etree.Element, child_tag: str) -> str: return _get_text_mandatory(_get_child_mandatory(parent, child_tag)) -def _child_text_mandatory_mapped(parent: etree.Element, child_tag: str, dct: Dict[str, T]) -> T: +def _child_text_mandatory_mapped(parent: etree._Element, child_tag: str, dct: Dict[str, T]) -> T: """ Shorthand for _get_text_mandatory_mapped() in combination with _get_child_mandatory(). @@ -393,7 +393,7 @@ def _child_text_mandatory_mapped(parent: etree.Element, child_tag: str, dct: Dic return _get_text_mandatory_mapped(_get_child_mandatory(parent, child_tag), dct) -def _get_kind(element: etree.Element) -> model.ModellingKind: +def _get_kind(element: etree._Element) -> model.ModellingKind: """ Returns the modelling kind of an element with the default value INSTANCE, if none specified. @@ -404,7 +404,7 @@ def _get_kind(element: etree.Element) -> model.ModellingKind: return modelling_kind if modelling_kind is not None else model.ModellingKind.INSTANCE -def _expect_reference_type(element: etree.Element, expected_type: Type[model.Reference]) -> None: +def _expect_reference_type(element: etree._Element, expected_type: Type[model.Reference]) -> None: """ Validates the type attribute of a Reference. @@ -430,7 +430,7 @@ class AASFromXmlDecoder: stripped = False @classmethod - def _amend_abstract_attributes(cls, obj: object, element: etree.Element) -> None: + def _amend_abstract_attributes(cls, obj: object, element: etree._Element) -> None: """ A helper function that amends optional attributes to already constructed class instances, if they inherit from an abstract class like Referable, Identifiable, HasSemantics or Qualifiable. @@ -489,7 +489,7 @@ def _amend_abstract_attributes(cls, obj: object, element: etree.Element) -> None obj.extension.add(extension) @classmethod - def _construct_relationship_element_internal(cls, element: etree.Element, object_class: Type[RE], **_kwargs: Any) \ + def _construct_relationship_element_internal(cls, element: etree._Element, object_class: Type[RE], **_kwargs: Any) \ -> RE: """ Helper function used by construct_relationship_element() and construct_annotated_relationship_element() @@ -504,7 +504,7 @@ def _construct_relationship_element_internal(cls, element: etree.Element, object return relationship_element @classmethod - def _construct_key_tuple(cls, element: etree.Element, namespace: str = NS_AAS, **_kwargs: Any) \ + def _construct_key_tuple(cls, element: etree._Element, namespace: str = NS_AAS, **_kwargs: Any) \ -> Tuple[model.Key, ...]: """ Helper function used by construct_reference() and construct_aas_reference() to reduce duplicate code @@ -513,7 +513,7 @@ def _construct_key_tuple(cls, element: etree.Element, namespace: str = NS_AAS, * return tuple(_child_construct_multiple(keys, namespace + "key", cls.construct_key, cls.failsafe)) @classmethod - def _construct_submodel_reference(cls, element: etree.Element, **kwargs: Any) \ + def _construct_submodel_reference(cls, element: etree._Element, **kwargs: Any) \ -> model.ModelReference[model.Submodel]: """ Helper function. Doesn't support the object_class parameter. Overwrite construct_aas_reference instead. @@ -521,7 +521,7 @@ def _construct_submodel_reference(cls, element: etree.Element, **kwargs: Any) \ return cls.construct_model_reference_expect_type(element, model.Submodel, **kwargs) @classmethod - def _construct_asset_administration_shell_reference(cls, element: etree.Element, **kwargs: Any) \ + def _construct_asset_administration_shell_reference(cls, element: etree._Element, **kwargs: Any) \ -> model.ModelReference[model.AssetAdministrationShell]: """ Helper function. Doesn't support the object_class parameter. Overwrite construct_aas_reference instead. @@ -529,7 +529,7 @@ def _construct_asset_administration_shell_reference(cls, element: etree.Element, return cls.construct_model_reference_expect_type(element, model.AssetAdministrationShell, **kwargs) @classmethod - def _construct_referable_reference(cls, element: etree.Element, **kwargs: Any) \ + def _construct_referable_reference(cls, element: etree._Element, **kwargs: Any) \ -> model.ModelReference[model.Referable]: """ Helper function. Doesn't support the object_class parameter. Overwrite construct_aas_reference instead. @@ -539,7 +539,7 @@ def _construct_referable_reference(cls, element: etree.Element, **kwargs: Any) \ return cls.construct_model_reference_expect_type(element, model.Referable, **kwargs) # type: ignore @classmethod - def _construct_operation_variable(cls, element: etree.Element, **kwargs: Any) -> model.SubmodelElement: + def _construct_operation_variable(cls, element: etree._Element, **kwargs: Any) -> model.SubmodelElement: """ Since we don't implement ``OperationVariable``, this constructor discards the wrapping `aas:operationVariable` and `aas:value` and just returns the contained :class:`~basyx.aas.model.submodel.SubmodelElement`. @@ -553,7 +553,7 @@ def _construct_operation_variable(cls, element: etree.Element, **kwargs: Any) -> return cls.construct_submodel_element(value[0], **kwargs) @classmethod - def construct_key(cls, element: etree.Element, object_class=model.Key, **_kwargs: Any) \ + def construct_key(cls, element: etree._Element, object_class=model.Key, **_kwargs: Any) \ -> model.Key: return object_class( _child_text_mandatory_mapped(element, NS_AAS + "type", KEY_TYPES_INVERSE), @@ -561,7 +561,7 @@ def construct_key(cls, element: etree.Element, object_class=model.Key, **_kwargs ) @classmethod - def construct_reference(cls, element: etree.Element, namespace: str = NS_AAS, **kwargs: Any) -> model.Reference: + def construct_reference(cls, element: etree._Element, namespace: str = NS_AAS, **kwargs: Any) -> model.Reference: reference_type: Type[model.Reference] = _child_text_mandatory_mapped(element, NS_AAS + "type", REFERENCE_TYPES_INVERSE) references: Dict[Type[model.Reference], Callable[..., model.Reference]] = { @@ -573,7 +573,7 @@ def construct_reference(cls, element: etree.Element, namespace: str = NS_AAS, ** return references[reference_type](element, namespace=namespace, **kwargs) @classmethod - def construct_external_reference(cls, element: etree.Element, namespace: str = NS_AAS, + def construct_external_reference(cls, element: etree._Element, namespace: str = NS_AAS, object_class=model.ExternalReference, **_kwargs: Any) \ -> model.ExternalReference: _expect_reference_type(element, model.ExternalReference) @@ -582,7 +582,7 @@ def construct_external_reference(cls, element: etree.Element, namespace: str = N cls.failsafe, namespace=namespace)) @classmethod - def construct_model_reference(cls, element: etree.Element, object_class=model.ModelReference, **_kwargs: Any) \ + def construct_model_reference(cls, element: etree._Element, object_class=model.ModelReference, **_kwargs: Any) \ -> model.ModelReference: """ This constructor for ModelReference determines the type of the ModelReference by its keys. If no keys are @@ -599,7 +599,7 @@ def construct_model_reference(cls, element: etree.Element, object_class=model.Mo cls.construct_reference, cls.failsafe)) @classmethod - def construct_model_reference_expect_type(cls, element: etree.Element, type_: Type[model.base._RT], + def construct_model_reference_expect_type(cls, element: etree._Element, type_: Type[model.base._RT], object_class=model.ModelReference, **_kwargs: Any) \ -> model.ModelReference[model.base._RT]: """ @@ -616,7 +616,7 @@ def construct_model_reference_expect_type(cls, element: etree.Element, type_: Ty cls.construct_reference, cls.failsafe)) @classmethod - def construct_administrative_information(cls, element: etree.Element, object_class=model.AdministrativeInformation, + def construct_administrative_information(cls, element: etree._Element, object_class=model.AdministrativeInformation, **_kwargs: Any) -> model.AdministrativeInformation: administrative_information = object_class( revision=_get_text_or_none(element.find(NS_AAS + "revision")), @@ -630,7 +630,7 @@ def construct_administrative_information(cls, element: etree.Element, object_cla return administrative_information @classmethod - def construct_lang_string_set(cls, element: etree.Element, expected_tag: str, object_class: Type[LSS], + def construct_lang_string_set(cls, element: etree._Element, expected_tag: str, object_class: Type[LSS], **_kwargs: Any) -> LSS: collected_lang_strings: Dict[str, str] = {} for lang_string_elem in _get_all_children_expect_tag(element, expected_tag, cls.failsafe): @@ -639,36 +639,36 @@ def construct_lang_string_set(cls, element: etree.Element, expected_tag: str, ob return object_class(collected_lang_strings) @classmethod - def construct_multi_language_name_type(cls, element: etree.Element, object_class=model.MultiLanguageNameType, + def construct_multi_language_name_type(cls, element: etree._Element, object_class=model.MultiLanguageNameType, **kwargs: Any) -> model.MultiLanguageNameType: return cls.construct_lang_string_set(element, NS_AAS + "langStringNameType", object_class, **kwargs) @classmethod - def construct_multi_language_text_type(cls, element: etree.Element, object_class=model.MultiLanguageTextType, + def construct_multi_language_text_type(cls, element: etree._Element, object_class=model.MultiLanguageTextType, **kwargs: Any) -> model.MultiLanguageTextType: return cls.construct_lang_string_set(element, NS_AAS + "langStringTextType", object_class, **kwargs) @classmethod - def construct_definition_type_iec61360(cls, element: etree.Element, object_class=model.DefinitionTypeIEC61360, + def construct_definition_type_iec61360(cls, element: etree._Element, object_class=model.DefinitionTypeIEC61360, **kwargs: Any) -> model.DefinitionTypeIEC61360: return cls.construct_lang_string_set(element, NS_AAS + "langStringDefinitionTypeIec61360", object_class, **kwargs) @classmethod - def construct_preferred_name_type_iec61360(cls, element: etree.Element, + def construct_preferred_name_type_iec61360(cls, element: etree._Element, object_class=model.PreferredNameTypeIEC61360, **kwargs: Any) -> model.PreferredNameTypeIEC61360: return cls.construct_lang_string_set(element, NS_AAS + "langStringPreferredNameTypeIec61360", object_class, **kwargs) @classmethod - def construct_short_name_type_iec61360(cls, element: etree.Element, object_class=model.ShortNameTypeIEC61360, + def construct_short_name_type_iec61360(cls, element: etree._Element, object_class=model.ShortNameTypeIEC61360, **kwargs: Any) -> model.ShortNameTypeIEC61360: return cls.construct_lang_string_set(element, NS_AAS + "langStringShortNameTypeIec61360", object_class, **kwargs) @classmethod - def construct_qualifier(cls, element: etree.Element, object_class=model.Qualifier, **_kwargs: Any) \ + def construct_qualifier(cls, element: etree._Element, object_class=model.Qualifier, **_kwargs: Any) \ -> model.Qualifier: qualifier = object_class( _child_text_mandatory(element, NS_AAS + "type"), @@ -687,7 +687,7 @@ def construct_qualifier(cls, element: etree.Element, object_class=model.Qualifie return qualifier @classmethod - def construct_extension(cls, element: etree.Element, object_class=model.Extension, **_kwargs: Any) \ + def construct_extension(cls, element: etree._Element, object_class=model.Extension, **_kwargs: Any) \ -> model.Extension: extension = object_class( _child_text_mandatory(element, NS_AAS + "name")) @@ -706,7 +706,7 @@ def construct_extension(cls, element: etree.Element, object_class=model.Extensio return extension @classmethod - def construct_submodel_element(cls, element: etree.Element, **kwargs: Any) -> model.SubmodelElement: + def construct_submodel_element(cls, element: etree._Element, **kwargs: Any) -> model.SubmodelElement: """ This function doesn't support the object_class parameter. Overwrite each individual SubmodelElement/DataElement constructor function instead. @@ -726,7 +726,7 @@ def construct_submodel_element(cls, element: etree.Element, **kwargs: Any) -> mo return submodel_elements[element.tag](element, **kwargs) @classmethod - def construct_data_element(cls, element: etree.Element, abstract_class_name: str = "DataElement", **kwargs: Any) \ + def construct_data_element(cls, element: etree._Element, abstract_class_name: str = "DataElement", **kwargs: Any) \ -> model.DataElement: """ This function does not support the object_class parameter. @@ -745,7 +745,7 @@ def construct_data_element(cls, element: etree.Element, abstract_class_name: str return data_elements[element.tag](element, **kwargs) @classmethod - def construct_annotated_relationship_element(cls, element: etree.Element, + def construct_annotated_relationship_element(cls, element: etree._Element, object_class=model.AnnotatedRelationshipElement, **_kwargs: Any) \ -> model.AnnotatedRelationshipElement: annotated_relationship_element = cls._construct_relationship_element_internal(element, object_class) @@ -758,7 +758,7 @@ def construct_annotated_relationship_element(cls, element: etree.Element, return annotated_relationship_element @classmethod - def construct_basic_event_element(cls, element: etree.Element, object_class=model.BasicEventElement, + def construct_basic_event_element(cls, element: etree._Element, object_class=model.BasicEventElement, **_kwargs: Any) -> model.BasicEventElement: basic_event_element = object_class( None, @@ -786,7 +786,7 @@ def construct_basic_event_element(cls, element: etree.Element, object_class=mode return basic_event_element @classmethod - def construct_blob(cls, element: etree.Element, object_class=model.Blob, **_kwargs: Any) -> model.Blob: + def construct_blob(cls, element: etree._Element, object_class=model.Blob, **_kwargs: Any) -> model.Blob: blob = object_class( None, _child_text_mandatory(element, NS_AAS + "contentType") @@ -798,14 +798,14 @@ def construct_blob(cls, element: etree.Element, object_class=model.Blob, **_kwar return blob @classmethod - def construct_capability(cls, element: etree.Element, object_class=model.Capability, **_kwargs: Any) \ + def construct_capability(cls, element: etree._Element, object_class=model.Capability, **_kwargs: Any) \ -> model.Capability: capability = object_class(None) cls._amend_abstract_attributes(capability, element) return capability @classmethod - def construct_entity(cls, element: etree.Element, object_class=model.Entity, **_kwargs: Any) -> model.Entity: + def construct_entity(cls, element: etree._Element, object_class=model.Entity, **_kwargs: Any) -> model.Entity: specific_asset_id = set() specific_assset_ids = element.find(NS_AAS + "specificAssetIds") if specific_assset_ids is not None: @@ -829,7 +829,7 @@ def construct_entity(cls, element: etree.Element, object_class=model.Entity, **_ return entity @classmethod - def construct_file(cls, element: etree.Element, object_class=model.File, **_kwargs: Any) -> model.File: + def construct_file(cls, element: etree._Element, object_class=model.File, **_kwargs: Any) -> model.File: file = object_class( None, _child_text_mandatory(element, NS_AAS + "contentType") @@ -841,7 +841,7 @@ def construct_file(cls, element: etree.Element, object_class=model.File, **_kwar return file @classmethod - def construct_resource(cls, element: etree.Element, object_class=model.Resource, **_kwargs: Any) -> model.Resource: + def construct_resource(cls, element: etree._Element, object_class=model.Resource, **_kwargs: Any) -> model.Resource: resource = object_class( _child_text_mandatory(element, NS_AAS + "path") ) @@ -852,7 +852,7 @@ def construct_resource(cls, element: etree.Element, object_class=model.Resource, return resource @classmethod - def construct_multi_language_property(cls, element: etree.Element, object_class=model.MultiLanguageProperty, + def construct_multi_language_property(cls, element: etree._Element, object_class=model.MultiLanguageProperty, **_kwargs: Any) -> model.MultiLanguageProperty: multi_language_property = object_class(None) value = _failsafe_construct(element.find(NS_AAS + "value"), cls.construct_multi_language_text_type, @@ -866,7 +866,7 @@ def construct_multi_language_property(cls, element: etree.Element, object_class= return multi_language_property @classmethod - def construct_operation(cls, element: etree.Element, object_class=model.Operation, **_kwargs: Any) \ + def construct_operation(cls, element: etree._Element, object_class=model.Operation, **_kwargs: Any) \ -> model.Operation: operation = object_class(None) for tag, target in ((NS_AAS + "inputVariables", operation.input_variable), @@ -881,7 +881,7 @@ def construct_operation(cls, element: etree.Element, object_class=model.Operatio return operation @classmethod - def construct_property(cls, element: etree.Element, object_class=model.Property, **_kwargs: Any) -> model.Property: + def construct_property(cls, element: etree._Element, object_class=model.Property, **_kwargs: Any) -> model.Property: property_ = object_class( None, value_type=_child_text_mandatory_mapped(element, NS_AAS + "valueType", model.datatypes.XSD_TYPE_CLASSES) @@ -896,7 +896,7 @@ def construct_property(cls, element: etree.Element, object_class=model.Property, return property_ @classmethod - def construct_range(cls, element: etree.Element, object_class=model.Range, **_kwargs: Any) -> model.Range: + def construct_range(cls, element: etree._Element, object_class=model.Range, **_kwargs: Any) -> model.Range: range_ = object_class( None, value_type=_child_text_mandatory_mapped(element, NS_AAS + "valueType", model.datatypes.XSD_TYPE_CLASSES) @@ -911,7 +911,7 @@ def construct_range(cls, element: etree.Element, object_class=model.Range, **_kw return range_ @classmethod - def construct_reference_element(cls, element: etree.Element, object_class=model.ReferenceElement, **_kwargs: Any) \ + def construct_reference_element(cls, element: etree._Element, object_class=model.ReferenceElement, **_kwargs: Any) \ -> model.ReferenceElement: reference_element = object_class(None) value = _failsafe_construct(element.find(NS_AAS + "value"), cls.construct_reference, cls.failsafe) @@ -921,12 +921,13 @@ def construct_reference_element(cls, element: etree.Element, object_class=model. return reference_element @classmethod - def construct_relationship_element(cls, element: etree.Element, object_class=model.RelationshipElement, + def construct_relationship_element(cls, element: etree._Element, object_class=model.RelationshipElement, **_kwargs: Any) -> model.RelationshipElement: return cls._construct_relationship_element_internal(element, object_class=object_class, **_kwargs) @classmethod - def construct_submodel_element_collection(cls, element: etree.Element, object_class=model.SubmodelElementCollection, + def construct_submodel_element_collection(cls, element: etree._Element, + object_class=model.SubmodelElementCollection, **_kwargs: Any) -> model.SubmodelElementCollection: collection = object_class(None) if not cls.stripped: @@ -939,7 +940,7 @@ def construct_submodel_element_collection(cls, element: etree.Element, object_cl return collection @classmethod - def construct_submodel_element_list(cls, element: etree.Element, object_class=model.SubmodelElementList, + def construct_submodel_element_list(cls, element: etree._Element, object_class=model.SubmodelElementList, **_kwargs: Any) -> model.SubmodelElementList: type_value_list_element = KEY_TYPES_CLASSES_INVERSE[ _child_text_mandatory_mapped(element, NS_AAS + "typeValueListElement", KEY_TYPES_INVERSE)] @@ -965,7 +966,7 @@ def construct_submodel_element_list(cls, element: etree.Element, object_class=mo return list_ @classmethod - def construct_asset_administration_shell(cls, element: etree.Element, object_class=model.AssetAdministrationShell, + def construct_asset_administration_shell(cls, element: etree._Element, object_class=model.AssetAdministrationShell, **_kwargs: Any) -> model.AssetAdministrationShell: aas = object_class( id_=_child_text_mandatory(element, NS_AAS + "id"), @@ -986,7 +987,7 @@ def construct_asset_administration_shell(cls, element: etree.Element, object_cla return aas @classmethod - def construct_specific_asset_id(cls, element: etree.Element, object_class=model.SpecificAssetId, + def construct_specific_asset_id(cls, element: etree._Element, object_class=model.SpecificAssetId, **_kwargs: Any) -> model.SpecificAssetId: # semantic_id can't be applied by _amend_abstract_attributes because specificAssetId is immutable return object_class( @@ -998,7 +999,7 @@ def construct_specific_asset_id(cls, element: etree.Element, object_class=model. ) @classmethod - def construct_asset_information(cls, element: etree.Element, object_class=model.AssetInformation, **_kwargs: Any) \ + def construct_asset_information(cls, element: etree._Element, object_class=model.AssetInformation, **_kwargs: Any) \ -> model.AssetInformation: specific_asset_id = set() specific_assset_ids = element.find(NS_AAS + "specificAssetIds") @@ -1025,7 +1026,7 @@ def construct_asset_information(cls, element: etree.Element, object_class=model. return asset_information @classmethod - def construct_submodel(cls, element: etree.Element, object_class=model.Submodel, **_kwargs: Any) \ + def construct_submodel(cls, element: etree._Element, object_class=model.Submodel, **_kwargs: Any) \ -> model.Submodel: submodel = object_class( _child_text_mandatory(element, NS_AAS + "id"), @@ -1041,13 +1042,13 @@ def construct_submodel(cls, element: etree.Element, object_class=model.Submodel, return submodel @classmethod - def construct_value_reference_pair(cls, element: etree.Element, object_class=model.ValueReferencePair, + def construct_value_reference_pair(cls, element: etree._Element, object_class=model.ValueReferencePair, **_kwargs: Any) -> model.ValueReferencePair: return object_class(_child_text_mandatory(element, NS_AAS + "value"), _child_construct_mandatory(element, NS_AAS + "valueId", cls.construct_reference)) @classmethod - def construct_value_list(cls, element: etree.Element, **_kwargs: Any) -> model.ValueList: + def construct_value_list(cls, element: etree._Element, **_kwargs: Any) -> model.ValueList: """ This function doesn't support the object_class parameter, because ValueList is just a generic type alias. """ @@ -1059,7 +1060,7 @@ def construct_value_list(cls, element: etree.Element, **_kwargs: Any) -> model.V ) @classmethod - def construct_concept_description(cls, element: etree.Element, object_class=model.ConceptDescription, + def construct_concept_description(cls, element: etree._Element, object_class=model.ConceptDescription, **_kwargs: Any) -> model.ConceptDescription: cd = object_class(_child_text_mandatory(element, NS_AAS + "id")) is_case_of = element.find(NS_AAS + "isCaseOf") @@ -1071,7 +1072,8 @@ def construct_concept_description(cls, element: etree.Element, object_class=mode return cd @classmethod - def construct_embedded_data_specification(cls, element: etree.Element, object_class=model.EmbeddedDataSpecification, + def construct_embedded_data_specification(cls, element: etree._Element, + object_class=model.EmbeddedDataSpecification, **_kwargs: Any) -> model.EmbeddedDataSpecification: data_specification_content = _get_child_mandatory(element, NS_AAS + "dataSpecificationContent") if len(data_specification_content) == 0: @@ -1087,7 +1089,7 @@ def construct_embedded_data_specification(cls, element: etree.Element, object_cl return embedded_data_specification @classmethod - def construct_data_specification_content(cls, element: etree.Element, **kwargs: Any) \ + def construct_data_specification_content(cls, element: etree._Element, **kwargs: Any) \ -> model.DataSpecificationContent: """ This function doesn't support the object_class parameter. @@ -1102,7 +1104,8 @@ def construct_data_specification_content(cls, element: etree.Element, **kwargs: return data_specification_contents[element.tag](element, **kwargs) @classmethod - def construct_data_specification_iec61360(cls, element: etree.Element, object_class=model.DataSpecificationIEC61360, + def construct_data_specification_iec61360(cls, element: etree._Element, + object_class=model.DataSpecificationIEC61360, **_kwargs: Any) -> model.DataSpecificationIEC61360: ds_iec = object_class(_child_construct_mandatory(element, NS_AAS + "preferredName", cls.construct_preferred_name_type_iec61360)) @@ -1186,7 +1189,7 @@ class StrictStrippedAASFromXmlDecoder(StrictAASFromXmlDecoder, StrippedAASFromXm pass -def _parse_xml_document(file: PathOrIO, failsafe: bool = True, **parser_kwargs: Any) -> Optional[etree.Element]: +def _parse_xml_document(file: PathOrIO, failsafe: bool = True, **parser_kwargs: Any) -> Optional[etree._Element]: """ Parse an XML document into an element tree diff --git a/basyx/aas/adapter/xml/xml_serialization.py b/basyx/aas/adapter/xml/xml_serialization.py index 9d7abfbdf..6f962c8f3 100644 --- a/basyx/aas/adapter/xml/xml_serialization.py +++ b/basyx/aas/adapter/xml/xml_serialization.py @@ -15,8 +15,8 @@ :func:`write_aas_xml_file`. - For serializing any object to an XML fragment, that fits the XML specification from 'Details of the Asset Administration Shell', chapter 5.4, you can either use :func:`object_to_xml_element`, which serializes a given - object and returns it as :class:`~lxml.etree.Element`, **or** :func:`write_aas_xml_element`, which does the same - thing, but writes the :class:`~lxml.etree.Element` to a file instead of returning it. + object and returns it as :class:`~lxml.etree._Element`, **or** :func:`write_aas_xml_element`, which does the same + thing, but writes the :class:`~lxml.etree._Element` to a file instead of returning it. As a third alternative, you can also use the functions ``_to_xml()`` directly. .. attention:: @@ -31,7 +31,7 @@ write_aas_xml_file(fp, object_store) """ -from lxml import etree # type: ignore +from lxml import etree from typing import Callable, Dict, Optional, Type import base64 @@ -47,14 +47,14 @@ def _generate_element(name: str, text: Optional[str] = None, - attributes: Optional[Dict] = None) -> etree.Element: + attributes: Optional[Dict] = None) -> etree._Element: """ - generate an :class:`~lxml.etree.Element` object + generate an :class:`~lxml.etree._Element` object :param name: namespace+tag_name of the element :param text: Text of the element. Default is None :param attributes: Attributes of the elements in form of a dict ``{"attribute_name": "attribute_content"}`` - :return: :class:`~lxml.etree.Element` object + :return: :class:`~lxml.etree._Element` object """ et_element = etree.Element(name) if text: @@ -83,7 +83,7 @@ def boolean_to_xml(obj: bool) -> str: # ############################################################## -def abstract_classes_to_xml(tag: str, obj: object) -> etree.Element: +def abstract_classes_to_xml(tag: str, obj: object) -> etree._Element: """ Generates an XML element and adds attributes of abstract base classes of ``obj``. @@ -151,14 +151,14 @@ def abstract_classes_to_xml(tag: str, obj: object) -> etree.Element: def _value_to_xml(value: model.ValueDataType, value_type: model.DataTypeDefXsd, - tag: str = NS_AAS+"value") -> etree.Element: + tag: str = NS_AAS+"value") -> etree._Element: """ Serialization of objects of :class:`~basyx.aas.model.base.ValueDataType` to XML :param value: :class:`~basyx.aas.model.base.ValueDataType` object :param value_type: Corresponding :class:`~basyx.aas.model.base.DataTypeDefXsd` :param tag: tag of the serialized :class:`~basyx.aas.model.base.ValueDataType` object - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ # todo: add "{NS_XSI+"type": "xs:"+model.datatypes.XSD_TYPE_NAMES[value_type]}" as attribute, if the schema allows # it @@ -167,13 +167,13 @@ def _value_to_xml(value: model.ValueDataType, text=model.datatypes.xsd_repr(value)) -def lang_string_set_to_xml(obj: model.LangStringSet, tag: str) -> etree.Element: +def lang_string_set_to_xml(obj: model.LangStringSet, tag: str) -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.LangStringSet` to XML :param obj: Object of class :class:`~basyx.aas.model.base.LangStringSet` :param tag: Namespace+Tag name of the returned XML element. - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ LANG_STRING_SET_TAGS: Dict[Type[model.LangStringSet], str] = {k: NS_AAS + v for k, v in { model.MultiLanguageNameType: "langStringNameType", @@ -192,13 +192,13 @@ def lang_string_set_to_xml(obj: model.LangStringSet, tag: str) -> etree.Element: def administrative_information_to_xml(obj: model.AdministrativeInformation, - tag: str = NS_AAS+"administration") -> etree.Element: + tag: str = NS_AAS+"administration") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.AdministrativeInformation` to XML :param obj: Object of class :class:`~basyx.aas.model.base.AdministrativeInformation` :param tag: Namespace+Tag of the serialized element. Default is ``aas:administration`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_administration = abstract_classes_to_xml(tag, obj) if obj.version: @@ -212,12 +212,12 @@ def administrative_information_to_xml(obj: model.AdministrativeInformation, return et_administration -def data_element_to_xml(obj: model.DataElement) -> etree.Element: +def data_element_to_xml(obj: model.DataElement) -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.DataElement` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.DataElement` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ if isinstance(obj, model.MultiLanguageProperty): return multi_language_property_to_xml(obj) @@ -231,15 +231,16 @@ def data_element_to_xml(obj: model.DataElement) -> etree.Element: return file_to_xml(obj) if isinstance(obj, model.ReferenceElement): return reference_element_to_xml(obj) + raise AssertionError(f"Type {obj.__class__.__name__} is not yet supported by the XML serialization!") -def key_to_xml(obj: model.Key, tag: str = NS_AAS+"key") -> etree.Element: +def key_to_xml(obj: model.Key, tag: str = NS_AAS+"key") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.Key` to XML :param obj: Object of class :class:`~basyx.aas.model.base.Key` :param tag: Namespace+Tag of the returned element. Default is ``aas:key`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_key = _generate_element(tag) et_key.append(_generate_element(name=NS_AAS + "type", text=_generic.KEY_TYPES[obj.type])) @@ -247,13 +248,13 @@ def key_to_xml(obj: model.Key, tag: str = NS_AAS+"key") -> etree.Element: return et_key -def reference_to_xml(obj: model.Reference, tag: str = NS_AAS+"reference") -> etree.Element: +def reference_to_xml(obj: model.Reference, tag: str = NS_AAS+"reference") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.Reference` to XML :param obj: Object of class :class:`~basyx.aas.model.base.Reference` :param tag: Namespace+Tag of the returned element. Default is ``aas:reference`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_reference = _generate_element(tag) et_reference.append(_generate_element(NS_AAS + "type", text=_generic.REFERENCE_TYPES[obj.__class__])) @@ -267,13 +268,13 @@ def reference_to_xml(obj: model.Reference, tag: str = NS_AAS+"reference") -> etr return et_reference -def qualifier_to_xml(obj: model.Qualifier, tag: str = NS_AAS+"qualifier") -> etree.Element: +def qualifier_to_xml(obj: model.Qualifier, tag: str = NS_AAS+"qualifier") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.Qualifier` to XML :param obj: Object of class :class:`~basyx.aas.model.base.Qualifier` :param tag: Namespace+Tag of the serialized ElementTree object. Default is ``aas:qualifier`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_qualifier = abstract_classes_to_xml(tag, obj) et_qualifier.append(_generate_element(NS_AAS + "kind", text=_generic.QUALIFIER_KIND[obj.kind])) @@ -286,13 +287,13 @@ def qualifier_to_xml(obj: model.Qualifier, tag: str = NS_AAS+"qualifier") -> etr return et_qualifier -def extension_to_xml(obj: model.Extension, tag: str = NS_AAS+"extension") -> etree.Element: +def extension_to_xml(obj: model.Extension, tag: str = NS_AAS+"extension") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.Extension` to XML :param obj: Object of class :class:`~basyx.aas.model.base.Extension` :param tag: Namespace+Tag of the serialized ElementTree object. Default is ``aas:extension`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_extension = abstract_classes_to_xml(tag, obj) et_extension.append(_generate_element(NS_AAS + "name", text=obj.name)) @@ -310,13 +311,13 @@ def extension_to_xml(obj: model.Extension, tag: str = NS_AAS+"extension") -> etr def value_reference_pair_to_xml(obj: model.ValueReferencePair, - tag: str = NS_AAS+"valueReferencePair") -> etree.Element: + tag: str = NS_AAS+"valueReferencePair") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.ValueReferencePair` to XML :param obj: Object of class :class:`~basyx.aas.model.base.ValueReferencePair` :param tag: Namespace+Tag of the serialized element. Default is ``aas:valueReferencePair`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_vrp = _generate_element(tag) # TODO: value_type isn't used at all by _value_to_xml(), thus we can ignore the type here for now @@ -326,7 +327,7 @@ def value_reference_pair_to_xml(obj: model.ValueReferencePair, def value_list_to_xml(obj: model.ValueList, - tag: str = NS_AAS+"valueList") -> etree.Element: + tag: str = NS_AAS+"valueList") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.ValueList` to XML @@ -334,7 +335,7 @@ def value_list_to_xml(obj: model.ValueList, :param obj: Object of class :class:`~basyx.aas.model.base.ValueList` :param tag: Namespace+Tag of the serialized element. Default is ``aas:valueList`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_value_list = _generate_element(tag) et_value_reference_pairs = _generate_element(NS_AAS+"valueReferencePairs") @@ -350,13 +351,13 @@ def value_list_to_xml(obj: model.ValueList, def specific_asset_id_to_xml(obj: model.SpecificAssetId, tag: str = NS_AAS + "specifidAssetId") \ - -> etree.Element: + -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.SpecificAssetId` to XML :param obj: Object of class :class:`~basyx.aas.model.base.SpecificAssetId` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:identifierKeyValuePair`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_asset_information = abstract_classes_to_xml(tag, obj) et_asset_information.append(_generate_element(name=NS_AAS + "name", text=obj.name)) @@ -367,13 +368,13 @@ def specific_asset_id_to_xml(obj: model.SpecificAssetId, tag: str = NS_AAS + "sp return et_asset_information -def asset_information_to_xml(obj: model.AssetInformation, tag: str = NS_AAS+"assetInformation") -> etree.Element: +def asset_information_to_xml(obj: model.AssetInformation, tag: str = NS_AAS+"assetInformation") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.aas.AssetInformation` to XML :param obj: Object of class :class:`~basyx.aas.model.aas.AssetInformation` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:assetInformation`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_asset_information = abstract_classes_to_xml(tag, obj) et_asset_information.append(_generate_element(name=NS_AAS + "assetKind", text=_generic.ASSET_KIND[obj.asset_kind])) @@ -393,13 +394,13 @@ def asset_information_to_xml(obj: model.AssetInformation, tag: str = NS_AAS+"ass def concept_description_to_xml(obj: model.ConceptDescription, - tag: str = NS_AAS+"conceptDescription") -> etree.Element: + tag: str = NS_AAS+"conceptDescription") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.concept.ConceptDescription` to XML :param obj: Object of class :class:`~basyx.aas.model.concept.ConceptDescription` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:conceptDescription`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_concept_description = abstract_classes_to_xml(tag, obj) if obj.is_case_of: @@ -411,13 +412,13 @@ def concept_description_to_xml(obj: model.ConceptDescription, def embedded_data_specification_to_xml(obj: model.EmbeddedDataSpecification, - tag: str = NS_AAS+"embeddedDataSpecification") -> etree.Element: + tag: str = NS_AAS+"embeddedDataSpecification") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.EmbeddedDataSpecification` to XML :param obj: Object of class :class:`~basyx.aas.model.base.EmbeddedDataSpecification` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:embeddedDataSpecification`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_embedded_data_specification = abstract_classes_to_xml(tag, obj) et_embedded_data_specification.append(reference_to_xml(obj.data_specification, tag=NS_AAS + "dataSpecification")) @@ -426,13 +427,13 @@ def embedded_data_specification_to_xml(obj: model.EmbeddedDataSpecification, def data_specification_content_to_xml(obj: model.DataSpecificationContent, - tag: str = NS_AAS+"dataSpecificationContent") -> etree.Element: + tag: str = NS_AAS+"dataSpecificationContent") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.DataSpecificationContent` to XML :param obj: Object of class :class:`~basyx.aas.model.base.DataSpecificationContent` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:dataSpecificationContent`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_data_specification_content = abstract_classes_to_xml(tag, obj) if isinstance(obj, model.DataSpecificationIEC61360): @@ -443,13 +444,13 @@ def data_specification_content_to_xml(obj: model.DataSpecificationContent, def data_specification_iec61360_to_xml(obj: model.DataSpecificationIEC61360, - tag: str = NS_AAS+"dataSpecificationIec61360") -> etree.Element: + tag: str = NS_AAS+"dataSpecificationIec61360") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.DataSpecificationIEC61360` to XML :param obj: Object of class :class:`~basyx.aas.model.base.DataSpecificationIEC61360` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:dataSpecificationIec61360`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_data_specification_iec61360 = abstract_classes_to_xml(tag, obj) et_data_specification_iec61360.append(lang_string_set_to_xml(obj.preferred_name, NS_AAS + "preferredName")) @@ -487,13 +488,13 @@ def data_specification_iec61360_to_xml(obj: model.DataSpecificationIEC61360, def asset_administration_shell_to_xml(obj: model.AssetAdministrationShell, - tag: str = NS_AAS+"assetAdministrationShell") -> etree.Element: + tag: str = NS_AAS+"assetAdministrationShell") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.aas.AssetAdministrationShell` to XML :param obj: Object of class :class:`~basyx.aas.model.aas.AssetAdministrationShell` :param tag: Namespace+Tag of the ElementTree object. Default is ``aas:assetAdministrationShell`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_aas = abstract_classes_to_xml(tag, obj) if obj.derived_from: @@ -512,12 +513,12 @@ def asset_administration_shell_to_xml(obj: model.AssetAdministrationShell, # ############################################################## -def submodel_element_to_xml(obj: model.SubmodelElement) -> etree.Element: +def submodel_element_to_xml(obj: model.SubmodelElement) -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.SubmodelElement` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.SubmodelElement` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ if isinstance(obj, model.DataElement): return data_element_to_xml(obj) @@ -537,16 +538,17 @@ def submodel_element_to_xml(obj: model.SubmodelElement) -> etree.Element: return submodel_element_collection_to_xml(obj) if isinstance(obj, model.SubmodelElementList): return submodel_element_list_to_xml(obj) + raise AssertionError(f"Type {obj.__class__.__name__} is not yet supported by the XML serialization!") def submodel_to_xml(obj: model.Submodel, - tag: str = NS_AAS+"submodel") -> etree.Element: + tag: str = NS_AAS+"submodel") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Submodel` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Submodel` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:submodel`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_submodel = abstract_classes_to_xml(tag, obj) if obj.submodel_element: @@ -558,13 +560,13 @@ def submodel_to_xml(obj: model.Submodel, def property_to_xml(obj: model.Property, - tag: str = NS_AAS+"property") -> etree.Element: + tag: str = NS_AAS+"property") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Property` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Property` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:property`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_property = abstract_classes_to_xml(tag, obj) et_property.append(_generate_element(NS_AAS + "valueType", text=model.datatypes.XSD_TYPE_NAMES[obj.value_type])) @@ -576,13 +578,13 @@ def property_to_xml(obj: model.Property, def multi_language_property_to_xml(obj: model.MultiLanguageProperty, - tag: str = NS_AAS+"multiLanguageProperty") -> etree.Element: + tag: str = NS_AAS+"multiLanguageProperty") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.MultiLanguageProperty` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.MultiLanguageProperty` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:multiLanguageProperty`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_multi_language_property = abstract_classes_to_xml(tag, obj) if obj.value: @@ -593,13 +595,13 @@ def multi_language_property_to_xml(obj: model.MultiLanguageProperty, def range_to_xml(obj: model.Range, - tag: str = NS_AAS+"range") -> etree.Element: + tag: str = NS_AAS+"range") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Range` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Range` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:range`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_range = abstract_classes_to_xml(tag, obj) et_range.append(_generate_element(name=NS_AAS + "valueType", @@ -612,13 +614,13 @@ def range_to_xml(obj: model.Range, def blob_to_xml(obj: model.Blob, - tag: str = NS_AAS+"blob") -> etree.Element: + tag: str = NS_AAS+"blob") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Blob` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Blob` :param tag: Namespace+Tag of the serialized element. Default is ``aas:blob`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_blob = abstract_classes_to_xml(tag, obj) et_value = etree.Element(NS_AAS + "value") @@ -630,13 +632,13 @@ def blob_to_xml(obj: model.Blob, def file_to_xml(obj: model.File, - tag: str = NS_AAS+"file") -> etree.Element: + tag: str = NS_AAS+"file") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.File` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.File` :param tag: Namespace+Tag of the serialized element. Default is ``aas:file`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_file = abstract_classes_to_xml(tag, obj) if obj.value: @@ -646,13 +648,13 @@ def file_to_xml(obj: model.File, def resource_to_xml(obj: model.Resource, - tag: str = NS_AAS+"resource") -> etree.Element: + tag: str = NS_AAS+"resource") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.base.Resource` to XML :param obj: Object of class :class:`~basyx.aas.model.base.Resource` :param tag: Namespace+Tag of the serialized element. Default is ``aas:resource`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_resource = abstract_classes_to_xml(tag, obj) et_resource.append(_generate_element(NS_AAS + "path", text=obj.path)) @@ -662,13 +664,13 @@ def resource_to_xml(obj: model.Resource, def reference_element_to_xml(obj: model.ReferenceElement, - tag: str = NS_AAS+"referenceElement") -> etree.Element: + tag: str = NS_AAS+"referenceElement") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.ReferenceElement` to XMl :param obj: Object of class :class:`~basyx.aas.model.submodel.ReferenceElement` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:referenceElement`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_reference_element = abstract_classes_to_xml(tag, obj) if obj.value: @@ -677,13 +679,13 @@ def reference_element_to_xml(obj: model.ReferenceElement, def submodel_element_collection_to_xml(obj: model.SubmodelElementCollection, - tag: str = NS_AAS+"submodelElementCollection") -> etree.Element: + tag: str = NS_AAS+"submodelElementCollection") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.SubmodelElementCollection` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.SubmodelElementCollection` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:submodelElementCollection`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_submodel_element_collection = abstract_classes_to_xml(tag, obj) if obj.value: @@ -695,13 +697,13 @@ def submodel_element_collection_to_xml(obj: model.SubmodelElementCollection, def submodel_element_list_to_xml(obj: model.SubmodelElementList, - tag: str = NS_AAS+"submodelElementList") -> etree.Element: + tag: str = NS_AAS+"submodelElementList") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.SubmodelElementList` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.SubmodelElementList` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:submodelElementList`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_submodel_element_list = abstract_classes_to_xml(tag, obj) et_submodel_element_list.append(_generate_element(NS_AAS + "orderRelevant", boolean_to_xml(obj.order_relevant))) @@ -722,13 +724,13 @@ def submodel_element_list_to_xml(obj: model.SubmodelElementList, def relationship_element_to_xml(obj: model.RelationshipElement, - tag: str = NS_AAS+"relationshipElement") -> etree.Element: + tag: str = NS_AAS+"relationshipElement") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.RelationshipElement` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.RelationshipElement` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:relationshipElement`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_relationship_element = abstract_classes_to_xml(tag, obj) et_relationship_element.append(reference_to_xml(obj.first, NS_AAS+"first")) @@ -737,13 +739,13 @@ def relationship_element_to_xml(obj: model.RelationshipElement, def annotated_relationship_element_to_xml(obj: model.AnnotatedRelationshipElement, - tag: str = NS_AAS+"annotatedRelationshipElement") -> etree.Element: + tag: str = NS_AAS+"annotatedRelationshipElement") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.AnnotatedRelationshipElement` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.AnnotatedRelationshipElement` :param tag: Namespace+Tag of the serialized element (optional): Default is ``aas:annotatedRelationshipElement`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_annotated_relationship_element = relationship_element_to_xml(obj, tag) if obj.annotation: @@ -754,7 +756,7 @@ def annotated_relationship_element_to_xml(obj: model.AnnotatedRelationshipElemen return et_annotated_relationship_element -def operation_variable_to_xml(obj: model.SubmodelElement, tag: str = NS_AAS+"operationVariable") -> etree.Element: +def operation_variable_to_xml(obj: model.SubmodelElement, tag: str = NS_AAS+"operationVariable") -> etree._Element: """ Serialization of :class:`~basyx.aas.model.submodel.SubmodelElement` to the XML OperationVariable representation Since we don't implement the ``OperationVariable`` class, which is just a wrapper for a single @@ -763,7 +765,7 @@ def operation_variable_to_xml(obj: model.SubmodelElement, tag: str = NS_AAS+"ope :param obj: Object of class :class:`~basyx.aas.model.submodel.SubmodelElement` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:operationVariable`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_operation_variable = _generate_element(tag) et_value = _generate_element(NS_AAS+"value") @@ -773,13 +775,13 @@ def operation_variable_to_xml(obj: model.SubmodelElement, tag: str = NS_AAS+"ope def operation_to_xml(obj: model.Operation, - tag: str = NS_AAS+"operation") -> etree.Element: + tag: str = NS_AAS+"operation") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Operation` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Operation` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:operation`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_operation = abstract_classes_to_xml(tag, obj) for tag, nss in ((NS_AAS+"inputVariables", obj.input_variable), @@ -794,25 +796,25 @@ def operation_to_xml(obj: model.Operation, def capability_to_xml(obj: model.Capability, - tag: str = NS_AAS+"capability") -> etree.Element: + tag: str = NS_AAS+"capability") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Capability` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Capability` :param tag: Namespace+Tag of the serialized element, default is ``aas:capability`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ return abstract_classes_to_xml(tag, obj) def entity_to_xml(obj: model.Entity, - tag: str = NS_AAS+"entity") -> etree.Element: + tag: str = NS_AAS+"entity") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.Entity` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.Entity` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:entity`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_entity = abstract_classes_to_xml(tag, obj) if obj.statement: @@ -831,13 +833,13 @@ def entity_to_xml(obj: model.Entity, return et_entity -def basic_event_element_to_xml(obj: model.BasicEventElement, tag: str = NS_AAS+"basicEventElement") -> etree.Element: +def basic_event_element_to_xml(obj: model.BasicEventElement, tag: str = NS_AAS+"basicEventElement") -> etree._Element: """ Serialization of objects of class :class:`~basyx.aas.model.submodel.BasicEventElement` to XML :param obj: Object of class :class:`~basyx.aas.model.submodel.BasicEventElement` :param tag: Namespace+Tag of the serialized element (optional). Default is ``aas:basicEventElement`` - :return: Serialized :class:`~lxml.etree.Element` object + :return: Serialized :class:`~lxml.etree._Element` object """ et_basic_event_element = abstract_classes_to_xml(tag, obj) et_basic_event_element.append(reference_to_xml(obj.observed, NS_AAS+"observed")) @@ -863,17 +865,17 @@ def basic_event_element_to_xml(obj: model.BasicEventElement, tag: str = NS_AAS+" # general functions # ############################################################## -def _write_element(file: _generic.PathOrBinaryIO, element: etree.Element, **kwargs) -> None: +def _write_element(file: _generic.PathOrBinaryIO, element: etree._Element, **kwargs) -> None: etree.ElementTree(element).write(file, encoding="UTF-8", xml_declaration=True, method="xml", **kwargs) -def object_to_xml_element(obj: object) -> etree.Element: +def object_to_xml_element(obj: object) -> etree._Element: """ - Serialize a single object to an :class:`~lxml.etree.Element`. + Serialize a single object to an :class:`~lxml.etree._Element`. :param obj: The object to serialize """ - serialization_func: Callable[..., etree.Element] + serialization_func: Callable[..., etree._Element] if isinstance(obj, model.Key): serialization_func = key_to_xml @@ -958,14 +960,14 @@ def write_aas_xml_element(file: _generic.PathOrBinaryIO, obj: object, **kwargs) :param file: A filename or file-like object to write the XML-serialized data to :param obj: The object to serialize - :param kwargs: Additional keyword arguments to be passed to :meth:`~lxml.etree.ElementTree.write` + :param kwargs: Additional keyword arguments to be passed to :meth:`~lxml.etree._ElementTree.write` """ return _write_element(file, object_to_xml_element(obj), **kwargs) -def object_store_to_xml_element(data: model.AbstractObjectStore) -> etree.Element: +def object_store_to_xml_element(data: model.AbstractObjectStore) -> etree._Element: """ - Serialize a set of AAS objects to an Asset Administration Shell as :class:`~lxml.etree.Element`. + Serialize a set of AAS objects to an Asset Administration Shell as :class:`~lxml.etree._Element`. This function is used internally by :meth:`write_aas_xml_file` and shouldn't be called directly for most use-cases. @@ -1015,6 +1017,6 @@ def write_aas_xml_file(file: _generic.PathOrBinaryIO, :param file: A filename or file-like object to write the XML-serialized data to :param data: :class:`ObjectStore ` which contains different objects of the AAS meta model which should be serialized to an XML file - :param kwargs: Additional keyword arguments to be passed to :meth:`~lxml.etree.ElementTree.write` + :param kwargs: Additional keyword arguments to be passed to :meth:`~lxml.etree._ElementTree.write` """ return _write_element(file, object_store_to_xml_element(data), **kwargs) diff --git a/test/adapter/xml/test_xml_deserialization.py b/test/adapter/xml/test_xml_deserialization.py index aebc3ad3a..8275dc033 100644 --- a/test/adapter/xml/test_xml_deserialization.py +++ b/test/adapter/xml/test_xml_deserialization.py @@ -13,7 +13,7 @@ from basyx.aas.adapter.xml import StrictAASFromXmlDecoder, XMLConstructables, read_aas_xml_file, \ read_aas_xml_file_into, read_aas_xml_element from basyx.aas.adapter._generic import XML_NS_MAP -from lxml import etree # type: ignore +from lxml import etree from typing import Iterable, Type, Union @@ -434,7 +434,7 @@ def __init__(self, *args, **kwargs): class EnhancedAASDecoder(StrictAASFromXmlDecoder): @classmethod - def construct_submodel(cls, element: etree.Element, object_class=EnhancedSubmodel, **kwargs) \ + def construct_submodel(cls, element: etree._Element, object_class=EnhancedSubmodel, **kwargs) \ -> model.Submodel: return super().construct_submodel(element, object_class=object_class, **kwargs) diff --git a/test/adapter/xml/test_xml_serialization.py b/test/adapter/xml/test_xml_serialization.py index 6d0e544a1..11328f62f 100644 --- a/test/adapter/xml/test_xml_serialization.py +++ b/test/adapter/xml/test_xml_serialization.py @@ -8,7 +8,7 @@ import os import unittest -from lxml import etree # type: ignore +from lxml import etree from basyx.aas import model from basyx.aas.adapter.xml import write_aas_xml_file, xml_serialization