From fde377608af981db85218a08a1a00b94c0a57d2c Mon Sep 17 00:00:00 2001 From: Sebastian Heppner Date: Fri, 11 Aug 2023 13:49:57 +0200 Subject: [PATCH 1/7] model.KeyTypes: Ignore mypy errors for abstract classes to be compliant Mypy appears to not like abstract classes in a context where only concrete classes should be given: ``` Only concrete class can be given where "tuple[type[Referable], KeyTypes]" is expected ``` However, the spec demands the four abstract classes - `Event` - `DataElement` - `SubmodelElement` - `SubmodelElementCollection` to appear inside the `model.KeyTypes` Enum. Therefore, we ignore these errors via `# type: ignore`. --- basyx/aas/model/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basyx/aas/model/__init__.py b/basyx/aas/model/__init__.py index 2b37a53fa..f66d29d8e 100644 --- a/basyx/aas/model/__init__.py +++ b/basyx/aas/model/__init__.py @@ -53,7 +53,7 @@ ConceptDictionary: KeyElements.CONCEPT_DICTIONARY, Entity: KeyElements.ENTITY, BasicEvent: KeyElements.BASIC_EVENT, - Event: KeyElements.EVENT, + Event: KeyElements.EVENT, # type: ignore Blob: KeyElements.BLOB, File: KeyElements.FILE, Operation: KeyElements.OPERATION, @@ -62,9 +62,9 @@ MultiLanguageProperty: KeyElements.MULTI_LANGUAGE_PROPERTY, Range: KeyElements.RANGE, ReferenceElement: KeyElements.REFERENCE_ELEMENT, - DataElement: KeyElements.DATA_ELEMENT, - SubmodelElementCollection: KeyElements.SUBMODEL_ELEMENT_COLLECTION, + DataElement: KeyElements.DATA_ELEMENT, # type: ignore + SubmodelElementCollection: KeyElements.SUBMODEL_ELEMENT_COLLECTION, # type: ignore AnnotatedRelationshipElement: KeyElements.ANNOTATED_RELATIONSHIP_ELEMENT, RelationshipElement: KeyElements.RELATIONSHIP_ELEMENT, - SubmodelElement: KeyElements.SUBMODEL_ELEMENT, + SubmodelElement: KeyElements.SUBMODEL_ELEMENT, # type: ignore } From bb5cfddd2e7fee531574c97058c2bac91cf44891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Otto?= Date: Wed, 7 Sep 2022 10:24:32 +0200 Subject: [PATCH 2/7] Fixed xml deserialization for missing prefixes --- basyx/aas/adapter/xml/xml_deserialization.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/basyx/aas/adapter/xml/xml_deserialization.py b/basyx/aas/adapter/xml/xml_deserialization.py index 4ca7bc294..551bde750 100644 --- a/basyx/aas/adapter/xml/xml_deserialization.py +++ b/basyx/aas/adapter/xml/xml_deserialization.py @@ -85,8 +85,9 @@ def _tag_replace_namespace(tag: str, nsmap: Dict[str, str]) -> str: """ split = tag.split("}") for prefix, namespace in nsmap.items(): - if namespace == split[0][1:]: - return prefix + ":" + split[1] + if prefix: + if namespace == split[0][1:]: + return prefix + ":" + split[1] return tag From 6fd70b833a0eaf7d4c62136407e193e2003435c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Otto?= Date: Thu, 28 Sep 2023 11:16:35 +0200 Subject: [PATCH 3/7] Simplify condition --- basyx/aas/adapter/xml/xml_deserialization.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/basyx/aas/adapter/xml/xml_deserialization.py b/basyx/aas/adapter/xml/xml_deserialization.py index 551bde750..5d4030698 100644 --- a/basyx/aas/adapter/xml/xml_deserialization.py +++ b/basyx/aas/adapter/xml/xml_deserialization.py @@ -85,9 +85,8 @@ def _tag_replace_namespace(tag: str, nsmap: Dict[str, str]) -> str: """ split = tag.split("}") for prefix, namespace in nsmap.items(): - if prefix: - if namespace == split[0][1:]: - return prefix + ":" + split[1] + if prefix and namespace == split[0][1:]: + return prefix + ":" + split[1] return tag From 1674911a67d57faf2d473013c43b237231cfcb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20M=C3=B6ller?= Date: Thu, 5 Oct 2023 16:44:49 +0200 Subject: [PATCH 4/7] model.datatypes: add `DateTimeStamp` to `AnyXSDType` The AAS Manager uses typehints to generate a list of possible types for a value. Since `DateTimeStamp` was missing, it was impossible to store a `DateTimeStamp` value via AAS Manager. --- basyx/aas/model/datatypes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basyx/aas/model/datatypes.py b/basyx/aas/model/datatypes.py index 4705ed6a9..0d02e25f3 100644 --- a/basyx/aas/model/datatypes.py +++ b/basyx/aas/model/datatypes.py @@ -375,10 +375,10 @@ def from_string(cls, value: str) -> "NormalizedString": AnyXSDType = Union[ - Duration, DayTimeDuration, YearMonthDuration, DateTime, Date, Time, GYearMonth, GYear, GMonthDay, GMonth, GDay, - Boolean, Base64Binary, HexBinary, Float, Double, Decimal, Integer, Long, Int, Short, Byte, NonPositiveInteger, - NegativeInteger, NonNegativeInteger, PositiveInteger, UnsignedLong, UnsignedInt, UnsignedShort, UnsignedByte, - AnyURI, String, NormalizedString] + Duration, DayTimeDuration, YearMonthDuration, DateTime, DateTimeStamp, Date, Time, GYearMonth, GYear, GMonthDay, + GMonth, GDay, Boolean, Base64Binary, HexBinary, Float, Double, Decimal, Integer, Long, Int, Short, Byte, + NonPositiveInteger, NegativeInteger, NonNegativeInteger, PositiveInteger, UnsignedLong, UnsignedInt, UnsignedShort, + UnsignedByte, AnyURI, String, NormalizedString] XSD_TYPE_NAMES: Dict[Type[AnyXSDType], str] = { From 4c98ba0ccef1e0d665b0511b5209e969772318b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20M=C3=B6ller?= Date: Fri, 3 Nov 2023 16:52:12 +0100 Subject: [PATCH 5/7] test.adapter.xml.xml_deserialization: remove unneeded 'type: ignore' comments --- test/adapter/xml/test_xml_deserialization.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/adapter/xml/test_xml_deserialization.py b/test/adapter/xml/test_xml_deserialization.py index 8597c145a..773e9848a 100644 --- a/test/adapter/xml/test_xml_deserialization.py +++ b/test/adapter/xml/test_xml_deserialization.py @@ -54,7 +54,7 @@ def _assertInExceptionAndLog(self, xml: str, strings: Union[Iterable[str], str], read_aas_xml_file(bytes_io, failsafe=False) cause = _root_cause(err_ctx.exception) for s in strings: - self.assertIn(s, log_ctx.output[0]) # type: ignore + self.assertIn(s, log_ctx.output[0]) self.assertIn(s, str(cause)) def test_malformed_xml(self) -> None: @@ -177,7 +177,7 @@ def test_reference_kind_mismatch(self) -> None: with self.assertLogs(logging.getLogger(), level=logging.WARNING) as context: read_aas_xml_file(io.BytesIO(xml.encode("utf-8")), failsafe=False) for s in ("GLOBAL_REFERENCE", "IRI=http://acplt.org/test_ref", "Asset"): - self.assertIn(s, context.output[0]) # type: ignore + self.assertIn(s, context.output[0]) def test_invalid_submodel_element(self) -> None: # TODO: simplify this should our suggestion regarding the XML schema get accepted @@ -265,7 +265,7 @@ def test_operation_variable_too_many_submodel_elements(self) -> None: """) with self.assertLogs(logging.getLogger(), level=logging.WARNING) as context: read_aas_xml_file(io.BytesIO(xml.encode("utf-8")), failsafe=False) - self.assertIn("aas:value", context.output[0]) # type: ignore + self.assertIn("aas:value", context.output[0]) def test_duplicate_identifier(self) -> None: xml = _xml_wrap(""" @@ -319,7 +319,7 @@ def get_clean_store() -> model.DictObjectStore: with self.assertLogs(logging.getLogger(), level=logging.INFO) as log_ctx: identifiers = read_aas_xml_file_into(object_store, bytes_io, replace_existing=False, ignore_existing=True) self.assertEqual(len(identifiers), 0) - self.assertIn("already exists in the object store", log_ctx.output[0]) # type: ignore + self.assertIn("already exists in the object store", log_ctx.output[0]) submodel = object_store.pop() self.assertIsInstance(submodel, model.Submodel) self.assertEqual(submodel.id_short, "test123") From 662ccf6ad05254e0b2965f2ff643efcd1005d2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20M=C3=B6ller?= Date: Fri, 3 Nov 2023 16:55:14 +0100 Subject: [PATCH 6/7] test.adapter.xml.xml_deserialization: make `OperationVariable` tests more explicit --- test/adapter/xml/test_xml_deserialization.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/adapter/xml/test_xml_deserialization.py b/test/adapter/xml/test_xml_deserialization.py index 773e9848a..714dee132 100644 --- a/test/adapter/xml/test_xml_deserialization.py +++ b/test/adapter/xml/test_xml_deserialization.py @@ -232,7 +232,7 @@ def test_operation_variable_no_submodel_element(self) -> None: """) - self._assertInExceptionAndLog(xml, "aas:value", KeyError, logging.ERROR) + self._assertInExceptionAndLog(xml, ["aas:value", "has no submodel element"], KeyError, logging.ERROR) def test_operation_variable_too_many_submodel_elements(self) -> None: # TODO: simplify this should our suggestion regarding the XML schema get accepted @@ -266,6 +266,7 @@ def test_operation_variable_too_many_submodel_elements(self) -> None: with self.assertLogs(logging.getLogger(), level=logging.WARNING) as context: read_aas_xml_file(io.BytesIO(xml.encode("utf-8")), failsafe=False) self.assertIn("aas:value", context.output[0]) + self.assertIn("more than one submodel element", context.output[0]) def test_duplicate_identifier(self) -> None: xml = _xml_wrap(""" From 6d58ca7e1c415f45e7c0ec24f48132f2dc2781d1 Mon Sep 17 00:00:00 2001 From: Sebastian Heppner Date: Tue, 21 Nov 2023 14:07:00 +0100 Subject: [PATCH 7/7] test.adapter.xml: Reintroduce "# type: ignore" tags that got lost in merge --- test/adapter/xml/test_xml_deserialization.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/adapter/xml/test_xml_deserialization.py b/test/adapter/xml/test_xml_deserialization.py index 360efe612..9310e4462 100644 --- a/test/adapter/xml/test_xml_deserialization.py +++ b/test/adapter/xml/test_xml_deserialization.py @@ -51,7 +51,7 @@ def _assertInExceptionAndLog(self, xml: str, strings: Union[Iterable[str], str], read_aas_xml_file(bytes_io, failsafe=False) cause = _root_cause(err_ctx.exception) for s in strings: - self.assertIn(s, log_ctx.output[0]) + self.assertIn(s, log_ctx.output[0]) # type: ignore self.assertIn(s, str(cause)) def test_malformed_xml(self) -> None: @@ -255,7 +255,7 @@ def test_operation_variable_too_many_submodel_elements(self) -> None: """) with self.assertLogs(logging.getLogger(), level=logging.WARNING) as context: read_aas_xml_file(io.BytesIO(xml.encode("utf-8")), failsafe=False) - self.assertIn("aas:value", context.output[0]) + self.assertIn("aas:value", context.output[0]) # type: ignore self.assertIn("more than one submodel element", context.output[0]) def test_duplicate_identifier(self) -> None: