Source code for aas_core3.verification

"""
Verify that the instances of the meta-model satisfy the invariants.

Here is an example how to verify an instance of :py:class:`aas_core3.types.Extension`:

.. code-block::

    import aas_core3.types as aas_types
    import aas_core3.verification as aas_verification

    an_instance = aas_types.Extension(
        # ... some constructor arguments ...
    )

    for error in aas_verification.verify(an_instance):
        print(f"{error.cause} at: {error.path}")
"""

# This code has been automatically generated by aas-core-codegen.
# Do NOT edit or append.


import math
import re
import struct
import sys
from typing import (
    Callable,
    Iterable,
    Iterator,
    List,
    Mapping,
    Optional,
    Pattern,
    Sequence,
    Set,
    Union,
)

if sys.version_info >= (3, 8):
    from typing import Final
else:
    from typing_extensions import Final

from aas_core3 import (
    constants as aas_constants,
    types as aas_types,
)


[docs]class PropertySegment: """Represent a property access on a path to an erroneous value.""" #: Instance containing the property instance: Final[aas_types.Class] #: Name of the property name: Final[str]
[docs] def __init__(self, instance: aas_types.Class, name: str) -> None: """Initialize with the given values.""" self.instance = instance self.name = name
[docs] def __str__(self) -> str: return f".{self.name}"
[docs]class IndexSegment: """Represent an index access on a path to an erroneous value.""" #: Sequence containing the item at :py:attr:`~index` sequence: Final[Sequence[aas_types.Class]] #: Index of the item index: Final[int]
[docs] def __init__(self, sequence: Sequence[aas_types.Class], index: int) -> None: """Initialize with the given values.""" self.sequence = sequence self.index = index
[docs] def __str__(self) -> str: return f"[{self.index}]"
Segment = Union[PropertySegment, IndexSegment]
[docs]class Path: """Represent the relative path to the erroneous value."""
[docs] def __init__(self) -> None: """Initialize as an empty path.""" self._segments = [] # type: List[Segment]
@property def segments(self) -> Sequence[Segment]: """Get the segments of the path.""" return self._segments def _prepend(self, segment: Segment) -> None: """Insert the :paramref:`segment` in front of other segments.""" self._segments.insert(0, segment)
[docs] def __str__(self) -> str: return "".join(str(segment) for segment in self._segments)
[docs]class Error: """Represent a verification error in the data.""" #: Human-readable description of the error cause: Final[str] #: Path to the erroneous value path: Final[Path]
[docs] def __init__(self, cause: str) -> None: """Initialize as an error with an empty path.""" self.cause = cause self.path = Path()
[docs] def __repr__(self) -> str: return f"Error(path={self.path}, cause={self.cause})"
# noinspection SpellCheckingInspection def _construct_matches_id_short() -> Pattern[str]: pattern = "^[a-zA-Z][a-zA-Z0-9_]*$" return re.compile(pattern) _REGEX_MATCHES_ID_SHORT = _construct_matches_id_short()
[docs]def matches_id_short(text: str) -> bool: """Check that :paramref:`text` is a valid short ID.""" return _REGEX_MATCHES_ID_SHORT.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_version_type() -> Pattern[str]: pattern = "^(0|[1-9][0-9]*)$" return re.compile(pattern) _REGEX_MATCHES_VERSION_TYPE = _construct_matches_version_type()
[docs]def matches_version_type(text: str) -> bool: """Check that :paramref:`text` is a valid version string.""" return _REGEX_MATCHES_VERSION_TYPE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_revision_type() -> Pattern[str]: pattern = "^(0|[1-9][0-9]*)$" return re.compile(pattern) _REGEX_MATCHES_REVISION_TYPE = _construct_matches_revision_type()
[docs]def matches_revision_type(text: str) -> bool: """Check that :paramref:`text` is a valid revision string.""" return _REGEX_MATCHES_REVISION_TYPE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_date_time_utc() -> Pattern[str]: digit = "[0-9]" year_frag = f"-?(([1-9]{digit}{digit}{digit}+)|(0{digit}{digit}{digit}))" month_frag = "((0[1-9])|(1[0-2]))" day_frag = f"((0[1-9])|([12]{digit})|(3[01]))" hour_frag = f"(([01]{digit})|(2[0-3]))" minute_frag = f"[0-5]{digit}" second_frag = f"([0-5]{digit})(\\.{digit}+)?" end_of_day_frag = "24:00:00(\\.0+)?" timezone_frag = "(Z|\\+00:00|-00:00)" date_time_lexical_rep = f"{year_frag}-{month_frag}-{day_frag}T(({hour_frag}:{minute_frag}:{second_frag})|{end_of_day_frag}){timezone_frag}" pattern = f"^{date_time_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DATE_TIME_UTC = _construct_matches_xs_date_time_utc()
[docs]def matches_xs_date_time_utc(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:dateTime``. The time zone must be fixed to UTC. We verify only that the ``text`` matches a pre-defined pattern. We *do not* verify that the day of month is correct nor do we check for leap seconds. See: https://www.w3.org/TR/xmlschema-2/#dateTime :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DATE_TIME_UTC.match(text) is not None
[docs]def is_xs_date_time_utc(value: str) -> bool: """ Check that :paramref:`value` is a ``xs:dateTime`` with the time zone set to UTC. """ if not matches_xs_date_time_utc(value): return False date, _ = value.split("T") return is_xs_date(date)
# noinspection SpellCheckingInspection def _construct_matches_mime_type() -> Pattern[str]: tchar = "[!#$%&'*+\\-.^_`|~0-9a-zA-Z]" token = f"({tchar})+" type = f"{token}" subtype = f"{token}" ows = "[ \\t]*" obs_text = "[\\x80-\\xff]" qd_text = f"([\\t !#-\\[\\]-~]|{obs_text})" quoted_pair = f"\\\\([\\t !-~]|{obs_text})" quoted_string = f'"({qd_text}|{quoted_pair})*"' parameter = f"{token}=({token}|{quoted_string})" media_type = f"^{type}/{subtype}({ows};{ows}{parameter})*$" return re.compile(media_type) _REGEX_MATCHES_MIME_TYPE = _construct_matches_mime_type()
[docs]def matches_mime_type(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of MIME type. The definition has been taken from: https://www.rfc-editor.org/rfc/rfc7231#section-3.1.1.1, https://www.rfc-editor.org/rfc/rfc7230#section-3.2.3 and https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6. :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_MIME_TYPE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_rfc_2396() -> Pattern[str]: alphanum = "[a-zA-Z0-9]" mark = "[-_.!~*'()]" unreserved = f"({alphanum}|{mark})" hex = "([0-9]|[aA]|[bB]|[cC]|[dD]|[eE]|[fF]|[aA]|[bB]|[cC]|[dD]|[eE]|[fF])" escaped = f"%{hex}{hex}" pchar = f"({unreserved}|{escaped}|[:@&=+$,])" param = f"({pchar})*" segment = f"({pchar})*(;{param})*" path_segments = f"{segment}(/{segment})*" abs_path = f"/{path_segments}" scheme = "[a-zA-Z][a-zA-Z0-9+\\-.]*" userinfo = f"({unreserved}|{escaped}|[;:&=+$,])*" domainlabel = f"({alphanum}|{alphanum}({alphanum}|-)*{alphanum})" toplabel = f"([a-zA-Z]|[a-zA-Z]({alphanum}|-)*{alphanum})" hostname = f"({domainlabel}\\.)*{toplabel}(\\.)?" ipv4address = "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+" host = f"({hostname}|{ipv4address})" port = "[0-9]*" hostport = f"{host}(:{port})?" server = f"(({userinfo}@)?{hostport})?" reg_name = f"({unreserved}|{escaped}|[$,;:@&=+])+" authority = f"({server}|{reg_name})" net_path = f"//{authority}({abs_path})?" reserved = "[;/?:@&=+$,]" uric = f"({reserved}|{unreserved}|{escaped})" query = f"({uric})*" hier_part = f"({net_path}|{abs_path})(\\?{query})?" uric_no_slash = f"({unreserved}|{escaped}|[;?:@&=+$,])" opaque_part = f"{uric_no_slash}({uric})*" absoluteuri = f"{scheme}:({hier_part}|{opaque_part})" fragment = f"({uric})*" rel_segment = f"({unreserved}|{escaped}|[;@&=+$,])+" rel_path = f"{rel_segment}({abs_path})?" relativeuri = f"({net_path}|{abs_path}|{rel_path})(\\?{query})?" uri_reference = f"^({absoluteuri}|{relativeuri})?(#{fragment})?$" return re.compile(uri_reference) _REGEX_MATCHES_RFC_2396 = _construct_matches_rfc_2396()
[docs]def matches_rfc_2396(text: str) -> bool: """ Check that :paramref:`text` matches to the URI pattern defined in RFC 2396 The definition has been taken from: https://datatracker.ietf.org/doc/html/rfc2396 Note that RFX 2396 alone is not enough for specifying ``xs:anyURI`` for XSD version 1.0, as that specifies URI together with the amendment of RFC 2732. :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_RFC_2396.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_bcp_47() -> Pattern[str]: alphanum = "[a-zA-Z0-9]" singleton = "[0-9A-WY-Za-wy-z]" extension = f"{singleton}(-({alphanum}){{2,8}})+" extlang = "[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2}" irregular = "(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)" regular = "(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)" grandfathered = f"({irregular}|{regular})" language = f"([a-zA-Z]{{2,3}}(-{extlang})?|[a-zA-Z]{{4}}|[a-zA-Z]{{5,8}})" script = "[a-zA-Z]{4}" region = "([a-zA-Z]{2}|[0-9]{3})" variant = f"(({alphanum}){{5,8}}|[0-9]({alphanum}){{3}})" privateuse = f"[xX](-({alphanum}){{1,8}})+" langtag = f"{language}(-{script})?(-{region})?(-{variant})*(-{extension})*(-{privateuse})?" language_tag = f"({langtag}|{privateuse}|{grandfathered})" pattern = f"^{language_tag}$" return re.compile(pattern) _REGEX_MATCHES_BCP_47 = _construct_matches_bcp_47()
[docs]def matches_bcp_47(text: str) -> bool: """ Check that :paramref:`text` is a valid BCP 47 language tag. See: https://en.wikipedia.org/wiki/IETF_language_tag """ return _REGEX_MATCHES_BCP_47.match(text) is not None
[docs]def lang_strings_have_unique_languages( lang_strings: Iterable[aas_types.AbstractLangString], ) -> bool: """ Check that :paramref:`lang_strings` are specified each for a unique language. """ language_set = set() # type: Set[str] for lang_string in lang_strings: if lang_string.language in language_set: return False language_set.add(lang_string.language) return True
[docs]def qualifier_types_are_unique(qualifiers: Iterable[aas_types.Qualifier]) -> bool: """ Check that there are no duplicate :py:attr:`.types.Qualifier.type`'s in the :paramref:`qualifiers`. """ type_set = set() # type: Set[str] for qualifier in qualifiers: if qualifier.type in type_set: return False type_set.add(qualifier.type) return True
# noinspection SpellCheckingInspection def _construct_matches_xml_serializable_string() -> Pattern[str]: pattern = "^[\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd\\U00010000-\\U0010ffff]*$" return re.compile(pattern) _REGEX_MATCHES_XML_SERIALIZABLE_STRING = _construct_matches_xml_serializable_string()
[docs]def matches_xml_serializable_string(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of the Constraint AASd-130. Ensures that encoding is possible and interoperability between different serializations is possible. :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XML_SERIALIZABLE_STRING.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_any_uri() -> Pattern[str]: scheme = "[a-zA-Z][a-zA-Z0-9+\\-.]*" ucschar = "[\\xa0-\\ud7ff\\uf900-\\ufdcf\\ufdf0-\\uffef\\U00010000-\\U0001fffd\\U00020000-\\U0002fffd\\U00030000-\\U0003fffd\\U00040000-\\U0004fffd\\U00050000-\\U0005fffd\\U00060000-\\U0006fffd\\U00070000-\\U0007fffd\\U00080000-\\U0008fffd\\U00090000-\\U0009fffd\\U000a0000-\\U000afffd\\U000b0000-\\U000bfffd\\U000c0000-\\U000cfffd\\U000d0000-\\U000dfffd\\U000e1000-\\U000efffd]" iunreserved = f"([a-zA-Z0-9\\-._~]|{ucschar})" pct_encoded = "%[0-9A-Fa-f][0-9A-Fa-f]" sub_delims = "[!$&'()*+,;=]" iuserinfo = f"({iunreserved}|{pct_encoded}|{sub_delims}|:)*" h16 = "[0-9A-Fa-f]{1,4}" dec_octet = "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])" ipv4address = f"{dec_octet}\\.{dec_octet}\\.{dec_octet}\\.{dec_octet}" ls32 = f"({h16}:{h16}|{ipv4address})" ipv6address = f"(({h16}:){{6}}{ls32}|::({h16}:){{5}}{ls32}|({h16})?::({h16}:){{4}}{ls32}|(({h16}:)?{h16})?::({h16}:){{3}}{ls32}|(({h16}:){{0,2}}{h16})?::({h16}:){{2}}{ls32}|(({h16}:){{0,3}}{h16})?::{h16}:{ls32}|(({h16}:){{0,4}}{h16})?::{ls32}|(({h16}:){{0,5}}{h16})?::{h16}|(({h16}:){{0,6}}{h16})?::)" unreserved = "[a-zA-Z0-9\\-._~]" ipvfuture = f"[vV][0-9A-Fa-f]+\\.({unreserved}|{sub_delims}|:)+" ip_literal = f"\\[({ipv6address}|{ipvfuture})\\]" ireg_name = f"({iunreserved}|{pct_encoded}|{sub_delims})*" ihost = f"({ip_literal}|{ipv4address}|{ireg_name})" port = "[0-9]*" iauthority = f"({iuserinfo}@)?{ihost}(:{port})?" ipchar = f"({iunreserved}|{pct_encoded}|{sub_delims}|[:@])" isegment = f"({ipchar})*" ipath_abempty = f"(/{isegment})*" isegment_nz = f"({ipchar})+" ipath_absolute = f"/({isegment_nz}(/{isegment})*)?" ipath_rootless = f"{isegment_nz}(/{isegment})*" ipath_empty = f"({ipchar}){{0}}" ihier_part = f"(//{iauthority}{ipath_abempty}|{ipath_absolute}|{ipath_rootless}|{ipath_empty})" iprivate = "[\\ue000-\\uf8ff\\U000f0000-\\U000ffffd\\U00100000-\\U0010fffd]" iquery = f"({ipchar}|{iprivate}|[/?])*" ifragment = f"({ipchar}|[/?])*" isegment_nz_nc = f"({iunreserved}|{pct_encoded}|{sub_delims}|@)+" ipath_noscheme = f"{isegment_nz_nc}(/{isegment})*" irelative_part = f"(//{iauthority}{ipath_abempty}|{ipath_absolute}|{ipath_noscheme}|{ipath_empty})" irelative_ref = f"{irelative_part}(\\?{iquery})?(#{ifragment})?" iri = f"{scheme}:{ihier_part}(\\?{iquery})?(#{ifragment})?" iri_reference = f"({iri}|{irelative_ref})" pattern = f"^{iri_reference}$" return re.compile(pattern) _REGEX_MATCHES_XS_ANY_URI = _construct_matches_xs_any_uri()
[docs]def matches_xs_any_uri(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:anyURI``. See: https://www.w3.org/TR/xmlschema-2/#anyURI and https://datatracker.ietf.org/doc/html/rfc3987 :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_ANY_URI.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_base_64_binary() -> Pattern[str]: b04_char = "[AQgw]" b04 = f"{b04_char}\\x20?" b16_char = "[AEIMQUYcgkosw048]" b16 = f"{b16_char}\\x20?" b64_char = "[A-Za-z0-9+/]" b64 = f"{b64_char}\\x20?" b64quad = f"({b64}{b64}{b64}{b64})" b64_final_quad = f"({b64}{b64}{b64}{b64_char})" padded_8 = f"{b64}{b04}= ?=" padded_16 = f"{b64}{b64}{b16}=" b64final = f"({b64_final_quad}|{padded_16}|{padded_8})" base64_binary = f"({b64quad}*{b64final})?" pattern = f"^{base64_binary}$" return re.compile(pattern) _REGEX_MATCHES_XS_BASE_64_BINARY = _construct_matches_xs_base_64_binary()
[docs]def matches_xs_base_64_binary(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:base64Binary``. See: https://www.w3.org/TR/xmlschema-2/#base64Binary :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_BASE_64_BINARY.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_boolean() -> Pattern[str]: pattern = "^(true|false|1|0)$" return re.compile(pattern) _REGEX_MATCHES_XS_BOOLEAN = _construct_matches_xs_boolean()
[docs]def matches_xs_boolean(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:boolean``. See: https://www.w3.org/TR/xmlschema-2/#boolean :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_BOOLEAN.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_date() -> Pattern[str]: digit = "[0-9]" year_frag = f"-?(([1-9]{digit}{digit}{digit}+)|(0{digit}{digit}{digit}))" month_frag = "((0[1-9])|(1[0-2]))" day_frag = f"((0[1-9])|([12]{digit})|(3[01]))" minute_frag = f"[0-5]{digit}" timezone_frag = f"(Z|(\\+|-)((0{digit}|1[0-3]):{minute_frag}|14:00))" date_lexical_rep = f"{year_frag}-{month_frag}-{day_frag}{timezone_frag}?" pattern = f"^{date_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DATE = _construct_matches_xs_date()
[docs]def matches_xs_date(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:date``. See: https://www.w3.org/TR/xmlschema-2/#date :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DATE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_date_time() -> Pattern[str]: digit = "[0-9]" year_frag = f"-?(([1-9]{digit}{digit}{digit}+)|(0{digit}{digit}{digit}))" month_frag = "((0[1-9])|(1[0-2]))" day_frag = f"((0[1-9])|([12]{digit})|(3[01]))" hour_frag = f"(([01]{digit})|(2[0-3]))" minute_frag = f"[0-5]{digit}" second_frag = f"([0-5]{digit})(\\.{digit}+)?" end_of_day_frag = "24:00:00(\\.0+)?" timezone_frag = f"(Z|(\\+|-)((0{digit}|1[0-3]):{minute_frag}|14:00))" date_time_lexical_rep = f"{year_frag}-{month_frag}-{day_frag}T(({hour_frag}:{minute_frag}:{second_frag})|{end_of_day_frag}){timezone_frag}?" pattern = f"^{date_time_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DATE_TIME = _construct_matches_xs_date_time()
[docs]def matches_xs_date_time(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:dateTime``. See: https://www.w3.org/TR/xmlschema-2/#dateTime :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DATE_TIME.match(text) is not None
[docs]def is_xs_date_time(value: str) -> bool: """ Check that :paramref:`value` is a ``xs:dateTime`` with the time zone set to UTC. """ if not matches_xs_date_time(value): return False date, _ = value.split("T") return is_xs_date(date)
# noinspection SpellCheckingInspection def _construct_matches_xs_decimal() -> Pattern[str]: digit = "[0-9]" unsigned_no_decimal_pt_numeral = f"{digit}+" no_decimal_pt_numeral = f"(\\+|-)?{unsigned_no_decimal_pt_numeral}" frac_frag = f"{digit}+" unsigned_decimal_pt_numeral = ( f"({unsigned_no_decimal_pt_numeral}\\.{frac_frag}|\\.{frac_frag})" ) decimal_pt_numeral = f"(\\+|-)?{unsigned_decimal_pt_numeral}" decimal_lexical_rep = f"({decimal_pt_numeral}|{no_decimal_pt_numeral})" pattern = f"^{decimal_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DECIMAL = _construct_matches_xs_decimal()
[docs]def matches_xs_decimal(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:decimal``. See: https://www.w3.org/TR/xmlschema-2/#decimal :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DECIMAL.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_double() -> Pattern[str]: double_rep = ( "((\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?|-?INF|NaN)" ) pattern = f"^{double_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DOUBLE = _construct_matches_xs_double()
[docs]def matches_xs_double(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:double``. See: https://www.w3.org/TR/xmlschema-2/#double :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DOUBLE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_duration() -> Pattern[str]: duration_rep = "-?P((([0-9]+Y([0-9]+M)?([0-9]+D)?|([0-9]+M)([0-9]+D)?|([0-9]+D))(T(([0-9]+H)([0-9]+M)?([0-9]+(\\.[0-9]+)?S)?|([0-9]+M)([0-9]+(\\.[0-9]+)?S)?|([0-9]+(\\.[0-9]+)?S)))?)|(T(([0-9]+H)([0-9]+M)?([0-9]+(\\.[0-9]+)?S)?|([0-9]+M)([0-9]+(\\.[0-9]+)?S)?|([0-9]+(\\.[0-9]+)?S))))" pattern = f"^{duration_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DURATION = _construct_matches_xs_duration()
[docs]def matches_xs_duration(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:duration``. See: https://www.w3.org/TR/xmlschema-2/#duration :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DURATION.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_float() -> Pattern[str]: float_rep = ( "((\\+|-)?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([Ee](\\+|-)?[0-9]+)?|-?INF|NaN)" ) pattern = f"^{float_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_FLOAT = _construct_matches_xs_float()
[docs]def matches_xs_float(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:float``. See: https://www.w3.org/TR/xmlschema-2/#float :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_FLOAT.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_g_day() -> Pattern[str]: g_day_lexical_rep = ( "---(0[1-9]|[12][0-9]|3[01])(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" ) pattern = f"^{g_day_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_G_DAY = _construct_matches_xs_g_day()
[docs]def matches_xs_g_day(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:gDay``. See: https://www.w3.org/TR/xmlschema-2/#gDay :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_G_DAY.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_g_month() -> Pattern[str]: g_month_lexical_rep = ( "--(0[1-9]|1[0-2])(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" ) pattern = f"^{g_month_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_G_MONTH = _construct_matches_xs_g_month()
[docs]def matches_xs_g_month(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:gMonth``. See: https://www.w3.org/TR/xmlschema-2/#gMonth :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_G_MONTH.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_g_month_day() -> Pattern[str]: g_month_day_rep = "--(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" pattern = f"^{g_month_day_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_G_MONTH_DAY = _construct_matches_xs_g_month_day()
[docs]def matches_xs_g_month_day(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:gMonthDay``. See: https://www.w3.org/TR/xmlschema-2/#gMonthDay :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_G_MONTH_DAY.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_g_year() -> Pattern[str]: g_year_rep = ( "-?([1-9][0-9]{3,}|0[0-9]{3})(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" ) pattern = f"^{g_year_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_G_YEAR = _construct_matches_xs_g_year()
[docs]def matches_xs_g_year(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:gYear``. See: https://www.w3.org/TR/xmlschema-2/#gYear :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_G_YEAR.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_g_year_month() -> Pattern[str]: g_year_month_rep = "-?([1-9][0-9]{3,}|0[0-9]{3})-(0[1-9]|1[0-2])(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" pattern = f"^{g_year_month_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_G_YEAR_MONTH = _construct_matches_xs_g_year_month()
[docs]def matches_xs_g_year_month(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:gYearMonth``. See: https://www.w3.org/TR/xmlschema-2/#gYearMonth :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_G_YEAR_MONTH.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_hex_binary() -> Pattern[str]: hex_binary = "([0-9a-fA-F]{2})*" pattern = f"^{hex_binary}$" return re.compile(pattern) _REGEX_MATCHES_XS_HEX_BINARY = _construct_matches_xs_hex_binary()
[docs]def matches_xs_hex_binary(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:hexBinary``. See: https://www.w3.org/TR/xmlschema-2/#hexBinary :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_HEX_BINARY.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_time() -> Pattern[str]: time_rep = "(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?|(24:00:00(\\.0+)?))(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" pattern = f"^{time_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_TIME = _construct_matches_xs_time()
[docs]def matches_xs_time(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:time``. See: https://www.w3.org/TR/xmlschema-2/#time :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_TIME.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_integer() -> Pattern[str]: integer_rep = "[-+]?[0-9]+" pattern = f"^{integer_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_INTEGER = _construct_matches_xs_integer()
[docs]def matches_xs_integer(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:integer``. See: https://www.w3.org/TR/xmlschema-2/#integer :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_INTEGER.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_long() -> Pattern[str]: long_rep = "[-+]?0*[0-9]{1,20}" pattern = f"^{long_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_LONG = _construct_matches_xs_long()
[docs]def matches_xs_long(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:long``. See: https://www.w3.org/TR/xmlschema-2/#long :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_LONG.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_int() -> Pattern[str]: int_rep = "[-+]?0*[0-9]{1,10}" pattern = f"^{int_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_INT = _construct_matches_xs_int()
[docs]def matches_xs_int(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:int``. See: https://www.w3.org/TR/xmlschema-2/#int :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_INT.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_short() -> Pattern[str]: short_rep = "[-+]?0*[0-9]{1,5}" pattern = f"^{short_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_SHORT = _construct_matches_xs_short()
[docs]def matches_xs_short(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:short``. See: https://www.w3.org/TR/xmlschema-2/#short :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_SHORT.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_byte() -> Pattern[str]: byte_rep = "[-+]?0*[0-9]{1,3}" pattern = f"^{byte_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_BYTE = _construct_matches_xs_byte()
[docs]def matches_xs_byte(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:byte``. See: https://www.w3.org/TR/xmlschema-2/#byte :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_BYTE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_non_negative_integer() -> Pattern[str]: non_negative_integer_rep = "(-0|\\+?[0-9]+)" pattern = f"^{non_negative_integer_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_NON_NEGATIVE_INTEGER = _construct_matches_xs_non_negative_integer()
[docs]def matches_xs_non_negative_integer(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:nonNegativeInteger``. See: https://www.w3.org/TR/xmlschema-2/#nonNegativeInteger :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_NON_NEGATIVE_INTEGER.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_positive_integer() -> Pattern[str]: positive_integer_rep = "\\+?0*[1-9][0-9]*" pattern = f"^{positive_integer_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_POSITIVE_INTEGER = _construct_matches_xs_positive_integer()
[docs]def matches_xs_positive_integer(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:positiveInteger``. See: https://www.w3.org/TR/xmlschema-2/#positiveInteger :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_POSITIVE_INTEGER.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_unsigned_long() -> Pattern[str]: unsigned_long_rep = "(-0|\\+?0*[0-9]{1,20})" pattern = f"^{unsigned_long_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_UNSIGNED_LONG = _construct_matches_xs_unsigned_long()
[docs]def matches_xs_unsigned_long(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:unsignedLong``. See: https://www.w3.org/TR/xmlschema-2/#unsignedLong :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_UNSIGNED_LONG.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_unsigned_int() -> Pattern[str]: unsigned_int_rep = "(-0|\\+?0*[0-9]{1,10})" pattern = f"^{unsigned_int_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_UNSIGNED_INT = _construct_matches_xs_unsigned_int()
[docs]def matches_xs_unsigned_int(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:unsignedInt``. See: https://www.w3.org/TR/xmlschema-2/#unsignedInt :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_UNSIGNED_INT.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_unsigned_short() -> Pattern[str]: unsigned_short_rep = "(-0|\\+?0*[0-9]{1,5})" pattern = f"^{unsigned_short_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_UNSIGNED_SHORT = _construct_matches_xs_unsigned_short()
[docs]def matches_xs_unsigned_short(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:unsignedShort``. See: https://www.w3.org/TR/xmlschema-2/#unsignedShort :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_UNSIGNED_SHORT.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_unsigned_byte() -> Pattern[str]: unsigned_byte_rep = "(-0|\\+?0*[0-9]{1,3})" pattern = f"^{unsigned_byte_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_UNSIGNED_BYTE = _construct_matches_xs_unsigned_byte()
[docs]def matches_xs_unsigned_byte(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:unsignedByte``. See: https://www.w3.org/TR/xmlschema-2/#unsignedByte :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_UNSIGNED_BYTE.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_non_positive_integer() -> Pattern[str]: non_positive_integer_rep = "(\\+0|0|-[0-9]+)" pattern = f"^{non_positive_integer_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_NON_POSITIVE_INTEGER = _construct_matches_xs_non_positive_integer()
[docs]def matches_xs_non_positive_integer(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:nonPositiveInteger``. See: https://www.w3.org/TR/xmlschema-2/#nonPositiveInteger :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_NON_POSITIVE_INTEGER.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_negative_integer() -> Pattern[str]: negative_integer_rep = "(-0*[1-9][0-9]*)" pattern = f"^{negative_integer_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_NEGATIVE_INTEGER = _construct_matches_xs_negative_integer()
[docs]def matches_xs_negative_integer(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:negativeInteger``. See: https://www.w3.org/TR/xmlschema-2/#negativeInteger :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_NEGATIVE_INTEGER.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_string() -> Pattern[str]: pattern = "^[\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd\\U00010000-\\U0010ffff]*$" return re.compile(pattern) _REGEX_MATCHES_XS_STRING = _construct_matches_xs_string()
[docs]def matches_xs_string(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:string``. See: https://www.w3.org/TR/xmlschema-2/#string :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_STRING.match(text) is not None
def _is_leap_year(year: int) -> bool: """ Check if :paramref:`year` is a leap year. >>> _is_leap_year(2016) True >>> _is_leap_year(1700) False >>> _is_leap_year(1600) True >>> _is_leap_year(2000) True """ # We consider the years B.C. to be one-off. # # See the note at: https://www.w3.org/TR/xmlschema-2/#dateTime: # "'-0001' is the lexical representation of the year 1 Before Common Era # (1 BCE, sometimes written "1 BC")." # # Hence, -1 year in XML is 1 BCE, which is 0 year in astronomical years. if year < 0: year = abs(year) - 1 # See: https://en.wikipedia.org/wiki/Leap_year#Algorithm if year % 4 > 0: return False if year % 100 > 0: return True if year % 400 > 0: return False return True _DAYS_IN_MONTH: Mapping[int, int] = { 1: 31, # Please use _is_leap_year if you need to check # whether a concrete February has 28 or 29 days. 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31, } _DATE_PREFIX_RE = re.compile(r"^(-?[0-9]+)-([0-9]{2})-([0-9]{2})")
[docs]def is_xs_date(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:date``.""" if not matches_xs_date(value): return False # NOTE (mristin, 2022-11-23): # We can not use :py:func:`datetime.datetime.strptime` as it does not # handle years below 1000 correctly on Windows (*e.g.*, ``-999-01-01``). # NOTE (mristin, 2022-10-30): # We need to match the prefix as zone offsets are allowed in the dates. Optimally, # we would re-use the pattern matching from :py:func`matches_xs_date`, but this # would make the code generation and constraint inference for schemas much more # difficult. Hence, we sacrifice the efficiency a bit for the clearer code & code # generation. match = _DATE_PREFIX_RE.match(value) assert match is not None year = int(match.group(1)) month = int(match.group(2)) day = int(match.group(3)) # We do not accept year zero, # see the note at: https://www.w3.org/TR/xmlschema-2/#dateTime if year == 0: return False if day <= 0: return False if month <= 0 or month >= 13: return False if month == 2: max_days = 29 if _is_leap_year(year) else 28 else: max_days = _DAYS_IN_MONTH[month] if day > max_days: return False return True
[docs]def is_xs_double(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:double``.""" # We need to check explicitly for the regular expression since # ``float(.)`` is too permissive. For example, # it accepts "nan" although only "NaN" is valid. # See: https://www.w3.org/TR/xmlschema-2/#double if not matches_xs_double(value): return False converted = float(value) # Check that the value is either "INF" or "-INF". # Otherwise, the value is a decimal which is too big # to be represented as a double-precision floating point # number. # # Python simply rounds up/down to ``INF`` and ``-INF``, # respectively, if the number is too large. # For example: ``float("1e400") == math.inf`` if math.isinf(converted) and value != "INF" and value != "-INF": return False return True
[docs]def is_xs_float(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:float``.""" # We need to check explicitly for the regular expression since # ``float(.)`` is too permissive. For example, # it accepts "nan" although only "NaN" is valid. # See: https://www.w3.org/TR/xmlschema-2/#double if not matches_xs_float(value): return False converted = float(value) # Check that the value is either "INF" or "-INF". # Otherwise, the value is a decimal which is too big # to be represented as a single-precision floating point # number. # # Python simply rounds up/down to ``INF`` and ``-INF``, # respectively, if the number is too large. # For example: ``float("1e400") == math.inf`` if math.isinf(converted) and value != "INF" and value != "-INF": return False # Python uses double-precision floating point numbers. Since # we check for a single-precision one, we have to explicitly # see if the number is within a range of a single-precision # floating point numbers. try: _ = struct.pack(">f", converted) except OverflowError: return False return True
[docs]def is_xs_g_month_day(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:gMonthDay``.""" if not matches_xs_g_month_day(value): return False month = int(value[2:4]) day = int(value[5:7]) max_days = _DAYS_IN_MONTH[month] return day <= max_days
[docs]def is_xs_long(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:long``.""" if not matches_xs_long(value): return False converted = int(value) return -9223372036854775808 <= converted <= 9223372036854775807
[docs]def is_xs_int(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:int``.""" if not matches_xs_int(value): return False converted = int(value) return -2147483648 <= converted <= 2147483647
[docs]def is_xs_short(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:short``.""" if not matches_xs_short(value): return False converted = int(value) return -32768 <= converted <= 32767
[docs]def is_xs_byte(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:byte``.""" if not matches_xs_byte(value): return False converted = int(value) return -128 <= converted <= 127
[docs]def is_xs_unsigned_long(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:unsignedLong``.""" if not matches_xs_unsigned_long(value): return False converted = int(value) return 0 <= converted <= 18446744073709551615
[docs]def is_xs_unsigned_int(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:unsignedInt``.""" if not matches_xs_unsigned_int(value): return False converted = int(value) return 0 <= converted <= 4294967295
[docs]def is_xs_unsigned_short(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:unsignedShort``.""" if not matches_xs_unsigned_short(value): return False converted = int(value) return 0 <= converted <= 65535
[docs]def is_xs_unsigned_byte(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:unsignedByte``.""" if not matches_xs_unsigned_byte(value): return False converted = int(value) return 0 <= converted <= 255
_DATA_TYPE_DEF_XSD_TO_VALUE_CONSISTENCY: Mapping[ aas_types.DataTypeDefXSD, Callable[[str], bool] ] = { aas_types.DataTypeDefXSD.ANY_URI: matches_xs_any_uri, aas_types.DataTypeDefXSD.BASE_64_BINARY: matches_xs_base_64_binary, aas_types.DataTypeDefXSD.BOOLEAN: matches_xs_boolean, aas_types.DataTypeDefXSD.BYTE: is_xs_byte, aas_types.DataTypeDefXSD.DATE: is_xs_date, aas_types.DataTypeDefXSD.DATE_TIME: is_xs_date_time, aas_types.DataTypeDefXSD.DECIMAL: matches_xs_decimal, aas_types.DataTypeDefXSD.DOUBLE: is_xs_double, aas_types.DataTypeDefXSD.DURATION: matches_xs_duration, aas_types.DataTypeDefXSD.FLOAT: is_xs_float, aas_types.DataTypeDefXSD.G_DAY: matches_xs_g_day, aas_types.DataTypeDefXSD.G_MONTH: matches_xs_g_month, aas_types.DataTypeDefXSD.G_MONTH_DAY: is_xs_g_month_day, aas_types.DataTypeDefXSD.G_YEAR: matches_xs_g_year, aas_types.DataTypeDefXSD.G_YEAR_MONTH: matches_xs_g_year_month, aas_types.DataTypeDefXSD.HEX_BINARY: matches_xs_hex_binary, aas_types.DataTypeDefXSD.INT: is_xs_int, aas_types.DataTypeDefXSD.INTEGER: matches_xs_integer, aas_types.DataTypeDefXSD.LONG: is_xs_long, aas_types.DataTypeDefXSD.NEGATIVE_INTEGER: matches_xs_negative_integer, aas_types.DataTypeDefXSD.NON_NEGATIVE_INTEGER: matches_xs_non_negative_integer, aas_types.DataTypeDefXSD.NON_POSITIVE_INTEGER: matches_xs_non_positive_integer, aas_types.DataTypeDefXSD.POSITIVE_INTEGER: matches_xs_positive_integer, aas_types.DataTypeDefXSD.SHORT: is_xs_short, aas_types.DataTypeDefXSD.STRING: matches_xs_string, aas_types.DataTypeDefXSD.TIME: matches_xs_time, aas_types.DataTypeDefXSD.UNSIGNED_BYTE: is_xs_unsigned_byte, aas_types.DataTypeDefXSD.UNSIGNED_INT: is_xs_unsigned_int, aas_types.DataTypeDefXSD.UNSIGNED_LONG: is_xs_unsigned_long, aas_types.DataTypeDefXSD.UNSIGNED_SHORT: is_xs_unsigned_short, } assert all( data_type_def_xsd in _DATA_TYPE_DEF_XSD_TO_VALUE_CONSISTENCY for data_type_def_xsd in aas_types.DataTypeDefXSD )
[docs]def value_consistent_with_xsd_type( value: str, value_type: aas_types.DataTypeDefXSD ) -> bool: """ Check that :paramref:`value` is consistent with the given :paramref:`value_type`. """ return _DATA_TYPE_DEF_XSD_TO_VALUE_CONSISTENCY[value_type](value)
[docs]def is_model_reference_to( reference: aas_types.Reference, expected_type: aas_types.KeyTypes ) -> bool: """ Check that the target of the model reference matches the :paramref:`expected_type`. """ # pylint: disable=all return ( reference.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(reference.keys) != 0 and reference.keys[-1].type == expected_type )
[docs]def is_model_reference_to_referable(reference: aas_types.Reference) -> bool: """ Check that the target of the reference matches a :py:attr:`.constants.AAS_REFERABLES`. """ # pylint: disable=all return ( reference.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(reference.keys) != 0 and (reference.keys[-1].type in aas_constants.AAS_REFERABLES) )
[docs]def id_shorts_are_unique(referables: Iterable[aas_types.Referable]) -> bool: """ Check that all :py:attr:`.types.Referable.id_short` are unique among :paramref:`referables`. """ id_short_set = set() # type: Set[str] for referable in referables: if referable.id_short in id_short_set: return False if referable.id_short is not None: id_short_set.add(referable.id_short) return True
[docs]def id_shorts_of_variables_are_unique( input_variables: Optional[List[aas_types.OperationVariable]], output_variables: Optional[List[aas_types.OperationVariable]], inoutput_variables: Optional[List[aas_types.OperationVariable]], ) -> bool: """ Check that the :py:attr:`.types.Referable.id_short`'s among all the :paramref:`input_variables`, :paramref:`output_variables` and :paramref:`inoutput_variables` are unique. """ id_short_set = set() if input_variables is not None: for variable in input_variables: if variable.value.id_short is not None: if variable.value.id_short in id_short_set: return False id_short_set.add(variable.value.id_short) if output_variables is not None: for variable in output_variables: if variable.value.id_short is not None: if variable.value.id_short in id_short_set: return False id_short_set.add(variable.value.id_short) if inoutput_variables is not None: for variable in inoutput_variables: if variable.value.id_short is not None: if variable.value.id_short in id_short_set: return False id_short_set.add(variable.value.id_short) return True
[docs]def extension_names_are_unique(extensions: Iterable[aas_types.Extension]) -> bool: """ Check that all :py:attr:`.types.Extension.name` are unique among :paramref:`extensions`. """ name_set = set() # type: Set[str] for extension in extensions: if extension.name in name_set: return False name_set.add(extension.name) return True
[docs]def submodel_elements_have_identical_semantic_ids( elements: Iterable[aas_types.SubmodelElement], ) -> bool: """ Check that all :paramref:`elements` have the identical :py:attr:`.types.HasSemantics.semantic_id`. """ that_semantic_id = None # type: Optional[aas_types.Reference] for element in elements: if element.semantic_id is None: continue if that_semantic_id is None: that_semantic_id = element.semantic_id continue this_semantic_id = element.semantic_id if len(that_semantic_id.keys) != len(this_semantic_id.keys): return False for this_key, that_key in zip(this_semantic_id.keys, that_semantic_id.keys): if this_key.value != that_key.value: return False return True
# fmt: off _AAS_SUBMODEL_ELEMENTS_TO_TYPE: Mapping[ aas_types.AASSubmodelElements, type ] = { aas_types.AASSubmodelElements.ANNOTATED_RELATIONSHIP_ELEMENT: aas_types.AnnotatedRelationshipElement, aas_types.AASSubmodelElements.BASIC_EVENT_ELEMENT: aas_types.BasicEventElement, aas_types.AASSubmodelElements.BLOB: aas_types.Blob, aas_types.AASSubmodelElements.CAPABILITY: aas_types.Capability, aas_types.AASSubmodelElements.DATA_ELEMENT: aas_types.DataElement, aas_types.AASSubmodelElements.ENTITY: aas_types.Entity, aas_types.AASSubmodelElements.EVENT_ELEMENT: aas_types.EventElement, aas_types.AASSubmodelElements.FILE: aas_types.File, aas_types.AASSubmodelElements.MULTI_LANGUAGE_PROPERTY: aas_types.MultiLanguageProperty, aas_types.AASSubmodelElements.OPERATION: aas_types.Operation, aas_types.AASSubmodelElements.PROPERTY: aas_types.Property, aas_types.AASSubmodelElements.RANGE: aas_types.Range, aas_types.AASSubmodelElements.REFERENCE_ELEMENT: aas_types.ReferenceElement, aas_types.AASSubmodelElements.RELATIONSHIP_ELEMENT: aas_types.RelationshipElement, aas_types.AASSubmodelElements.SUBMODEL_ELEMENT: aas_types.SubmodelElement, aas_types.AASSubmodelElements.SUBMODEL_ELEMENT_LIST: aas_types.SubmodelElementList, aas_types.AASSubmodelElements.SUBMODEL_ELEMENT_COLLECTION: aas_types.SubmodelElementCollection, } # fmt: on def _assert_all_types_covered_in_aas_submodel_elements_to_type() -> None: """ Assert that we did not miss a type in :py:attr:`_AAS_SUBMODEL_ELEMENTS_TO_TYPE`. """ missing_literals = [ literal for literal in aas_types.AASSubmodelElements if literal not in _AAS_SUBMODEL_ELEMENTS_TO_TYPE ] assert len(missing_literals) == 0, ( f"Some literals were missed in " f"_AAS_SUBMODEL_ELEMENTS_TO_TYPE: {missing_literals!r}" ) _assert_all_types_covered_in_aas_submodel_elements_to_type()
[docs]def submodel_element_is_of_type( element: aas_types.SubmodelElement, expected_type: aas_types.AASSubmodelElements ) -> bool: """ Check that :paramref:`element` is an instance of class corresponding to :paramref:`expected_type`. """ # noinspection PyTypeHints return isinstance(element, _AAS_SUBMODEL_ELEMENTS_TO_TYPE[expected_type])
[docs]def properties_or_ranges_have_value_type( elements: Iterable[aas_types.SubmodelElement], value_type: aas_types.DataTypeDefXSD ) -> bool: """ Check that :paramref:`elements` which are :py:class:`.types.Property` or :py:class:`.types.Range` have the given :paramref:`value_type`. """ range_or_property = (aas_types.Property, aas_types.Range) for element in elements: if isinstance(element, range_or_property): if element.value_type is not value_type: return False return True
[docs]def reference_key_values_equal( that: aas_types.Reference, other: aas_types.Reference ) -> bool: """ Check that the two references, :paramref:`that` and :paramref:`other`, are equal by comparing their :py:attr:`.types.Reference.keys` by :py:attr:`.types.Key.value`'s. """ if len(that.keys) != len(other.keys): return False for that_key, other_key in zip(that.keys, other.keys): if that_key.value != other_key.value: return False return True
[docs]def data_specification_iec_61360s_for_property_or_value_have_appropriate_data_type( embedded_data_specifications: Iterable[aas_types.EmbeddedDataSpecification], ) -> bool: """ Check that :py:attr:`.types.DataSpecificationIEC61360.data_type` is defined appropriately for all data specifications whose content is given as IEC 61360. """ for embedded_data_specification in embedded_data_specifications: if isinstance( embedded_data_specification.data_specification_content, aas_types.DataSpecificationIEC61360, ): iec61360 = embedded_data_specification.data_specification_content if ( iec61360.data_type is None or iec61360.data_type not in aas_constants.DATA_TYPE_IEC_61360_FOR_PROPERTY_OR_VALUE ): return False return True
[docs]def data_specification_iec_61360s_for_reference_have_appropriate_data_type( embedded_data_specifications: Iterable[aas_types.EmbeddedDataSpecification], ) -> bool: """ Check that :py:attr:`.types.DataSpecificationIEC61360.data_type` is defined appropriately for all data specifications whose content is given as IEC 61360. """ for embedded_data_specification in embedded_data_specifications: if isinstance( embedded_data_specification.data_specification_content, aas_types.DataSpecificationIEC61360, ): iec61360 = embedded_data_specification.data_specification_content if ( iec61360.data_type is None or iec61360.data_type not in aas_constants.DATA_TYPE_IEC_61360_FOR_REFERENCE ): return False return True
[docs]def data_specification_iec_61360s_for_document_have_appropriate_data_type( embedded_data_specifications: Iterable[aas_types.EmbeddedDataSpecification], ) -> bool: """ Check that :py:attr:`.types.DataSpecificationIEC61360.data_type` is defined appropriately for all data specifications whose content is given as IEC 61360. """ for embedded_data_specification in embedded_data_specifications: if isinstance( embedded_data_specification.data_specification_content, aas_types.DataSpecificationIEC61360, ): iec61360 = embedded_data_specification.data_specification_content if ( iec61360.data_type is None or iec61360.data_type not in aas_constants.DATA_TYPE_IEC_61360_FOR_DOCUMENT ): return False return True
[docs]def data_specification_iec_61360s_have_data_type( embedded_data_specifications: Iterable[aas_types.EmbeddedDataSpecification], ) -> bool: """ Check that :py:attr:`.types.DataSpecificationIEC61360.data_type` is defined for all data specifications whose content is given as IEC 61360. """ for embedded_data_specification in embedded_data_specifications: if isinstance( embedded_data_specification.data_specification_content, aas_types.DataSpecificationIEC61360, ): iec61360 = embedded_data_specification.data_specification_content if iec61360.data_type is None: return False return True
[docs]def data_specification_iec_61360s_have_value( embedded_data_specifications: Iterable[aas_types.EmbeddedDataSpecification], ) -> bool: """ Check that :py:attr:`.types.DataSpecificationIEC61360.value` is defined for all data specifications whose content is given as IEC 61360. """ for embedded_data_specification in embedded_data_specifications: if isinstance( embedded_data_specification.data_specification_content, aas_types.DataSpecificationIEC61360, ): iec61360 = embedded_data_specification.data_specification_content if iec61360.value is None: return False return True
[docs]def data_specification_iec_61360s_have_definition_at_least_in_english( embedded_data_specifications: Iterable[aas_types.EmbeddedDataSpecification], ) -> bool: """ Check that :py:attr:`.types.DataSpecificationIEC61360.definition` is defined for all data specifications whose content is given as IEC 61360 at least in English. """ for embedded_data_specification in embedded_data_specifications: if isinstance( embedded_data_specification.data_specification_content, aas_types.DataSpecificationIEC61360, ): iec61360 = embedded_data_specification.data_specification_content if iec61360.definition is None: return False no_definition_in_english = True for lang_string in iec61360.definition: if is_bcp_47_for_english(lang_string.language): no_definition_in_english = False break if no_definition_in_english: return False return True
# noinspection SpellCheckingInspection def _construct_is_bcp_47_for_english() -> Pattern[str]: pattern = "^(en|EN)(-.*)?$" return re.compile(pattern) _REGEX_IS_BCP_47_FOR_ENGLISH = _construct_is_bcp_47_for_english()
[docs]def is_bcp_47_for_english(text: str) -> bool: """ Check that the :paramref:`text` corresponds to a BCP47 code for english. """ return _REGEX_IS_BCP_47_FOR_ENGLISH.match(text) is not None
class _Transformer(aas_types.AbstractTransformer[Iterator[Error]]): # noinspection PyMethodMayBeStatic def transform_extension(self, that: aas_types.Extension) -> Iterator[Error]: if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.refers_to is not None) or (len(that.refers_to) >= 1)): yield Error("Refers-to must be either not set or have at least one item.") if not ( not (that.value is not None) or value_consistent_with_xsd_type(that.value, that.value_type_or_default()) ): yield Error("The value must match the value type.") if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, an_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error for error in verify_name_type(that.name): error.path._prepend(PropertySegment(that, "name")) yield error if that.value is not None: for error in verify_value_data_type(that.value): error.path._prepend(PropertySegment(that, "value")) yield error if that.refers_to is not None: for i, another_item in enumerate(that.refers_to): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.refers_to, i)) error.path._prepend(PropertySegment(that, "refers_to")) yield error # noinspection PyMethodMayBeStatic def transform_administrative_information( self, that: aas_types.AdministrativeInformation ) -> Iterator[Error]: if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.revision is not None) or (that.version is not None)): yield Error( "Constraint AASd-005: If version is not specified then also " + "revision shall be unspecified. This means, a revision " + "requires a version. If there is no version there is no " + "revision either. Revision is optional." ) if that.embedded_data_specifications is not None: for i, an_item in enumerate(that.embedded_data_specifications): for error in self.transform(an_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.version is not None: for error in verify_version_type(that.version): error.path._prepend(PropertySegment(that, "version")) yield error if that.revision is not None: for error in verify_revision_type(that.revision): error.path._prepend(PropertySegment(that, "revision")) yield error if that.creator is not None: for error in self.transform(that.creator): error.path._prepend(PropertySegment(that, "creator")) yield error if that.template_id is not None: for error in verify_identifier(that.template_id): error.path._prepend(PropertySegment(that, "template_id")) yield error # noinspection PyMethodMayBeStatic def transform_qualifier(self, that: aas_types.Qualifier) -> Iterator[Error]: if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not ( not (that.value is not None) or value_consistent_with_xsd_type(that.value, that.value_type) ): yield Error( "Constraint AASd-020: The value shall be consistent to " + "the data type as defined in value type." ) if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, an_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error for error in verify_qualifier_type(that.type): error.path._prepend(PropertySegment(that, "type")) yield error if that.value is not None: for error in verify_value_data_type(that.value): error.path._prepend(PropertySegment(that, "value")) yield error if that.value_id is not None: for error in self.transform(that.value_id): error.path._prepend(PropertySegment(that, "value_id")) yield error # noinspection PyMethodMayBeStatic def transform_asset_administration_shell( self, that: aas_types.AssetAdministrationShell ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.submodels is not None) or (len(that.submodels) >= 1)): yield Error("Submodels must be either not set or have at least one item.") if not ( not (that.derived_from is not None) or is_model_reference_to( that.derived_from, aas_types.KeyTypes.ASSET_ADMINISTRATION_SHELL ) ): yield Error( "Derived-from must be a model reference to an asset " + "administration shell." ) if not ( not (that.submodels is not None) or ( all( is_model_reference_to(reference, aas_types.KeyTypes.SUBMODEL) for reference in that.submodels ) ) ): yield Error("All submodels must be model references to a submodel.") if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.administration is not None: for error in self.transform(that.administration): error.path._prepend(PropertySegment(that, "administration")) yield error for error in verify_identifier(that.id): error.path._prepend(PropertySegment(that, "id")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_another_item in enumerate(that.embedded_data_specifications): for error in self.transform(yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.derived_from is not None: for error in self.transform(that.derived_from): error.path._prepend(PropertySegment(that, "derived_from")) yield error for error in self.transform(that.asset_information): error.path._prepend(PropertySegment(that, "asset_information")) yield error if that.submodels is not None: for i, yet_yet_yet_another_item in enumerate(that.submodels): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.submodels, i)) error.path._prepend(PropertySegment(that, "submodels")) yield error # noinspection PyMethodMayBeStatic def transform_asset_information( self, that: aas_types.AssetInformation ) -> Iterator[Error]: if not ( not (that.specific_asset_ids is not None) or ( all( ( specific_asset_id.name != "globalAssetId" or ( ( (that.global_asset_id is not None) and specific_asset_id.name == "globalAssetId" and specific_asset_id.value == that.global_asset_id ) ) ) for specific_asset_id in that.specific_asset_ids ) ) ): yield Error( "Constraint AASd-116: ``globalAssetId`` is a reserved key. " + "If used as value for the name of specific asset ID then " + "the value of specific asset ID shall be identical to " + "the global asset ID." ) if not ( ( ( ( (that.global_asset_id is not None) or (that.specific_asset_ids is not None) ) ) and ( not (that.specific_asset_ids is not None) or (len(that.specific_asset_ids) >= 1) ) ) ): yield Error( "Constraint AASd-131: Either the global asset ID shall be " + "defined or at least one specific asset ID." ) if not ( not (that.specific_asset_ids is not None) or (len(that.specific_asset_ids) >= 1) ): yield Error( "Specific asset IDs must be either not set or have at least " + "one item." ) if that.global_asset_id is not None: for error in verify_identifier(that.global_asset_id): error.path._prepend(PropertySegment(that, "global_asset_id")) yield error if that.specific_asset_ids is not None: for i, an_item in enumerate(that.specific_asset_ids): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.specific_asset_ids, i)) error.path._prepend(PropertySegment(that, "specific_asset_ids")) yield error if that.asset_type is not None: for error in verify_identifier(that.asset_type): error.path._prepend(PropertySegment(that, "asset_type")) yield error if that.default_thumbnail is not None: for error in self.transform(that.default_thumbnail): error.path._prepend(PropertySegment(that, "default_thumbnail")) yield error # noinspection PyMethodMayBeStatic def transform_resource(self, that: aas_types.Resource) -> Iterator[Error]: for error in verify_path_type(that.path): error.path._prepend(PropertySegment(that, "path")) yield error if that.content_type is not None: for error in verify_content_type(that.content_type): error.path._prepend(PropertySegment(that, "content_type")) yield error # noinspection PyMethodMayBeStatic def transform_specific_asset_id( self, that: aas_types.SpecificAssetID ) -> Iterator[Error]: if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not ( not (that.external_subject_id is not None) or ( that.external_subject_id.type == aas_types.ReferenceTypes.EXTERNAL_REFERENCE ) ): yield Error( "Constraint AASd-133: External subject ID shall be " + "an external reference." ) if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, an_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error for error in verify_label_type(that.name): error.path._prepend(PropertySegment(that, "name")) yield error for error in verify_identifier(that.value): error.path._prepend(PropertySegment(that, "value")) yield error if that.external_subject_id is not None: for error in self.transform(that.external_subject_id): error.path._prepend(PropertySegment(that, "external_subject_id")) yield error # noinspection PyMethodMayBeStatic def transform_submodel(self, that: aas_types.Submodel) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.submodel_elements is not None) or (len(that.submodel_elements) >= 1) ): yield Error( "Submodel elements must be either not set or have at least " + "one item." ) if not ( not (that.submodel_elements is not None) or (all(item.id_short is not None for item in that.submodel_elements)) ): yield Error( "ID-shorts need to be defined for all the items of submodel " + "elements according to AASd-117 (ID-short of Referables not " + "being a direct child of a Submodel element list shall be " + "specified)." ) if not ( not (that.submodel_elements is not None) or id_shorts_are_unique(that.submodel_elements) ): yield Error( "Constraint AASd-022: ID-short of non-identifiable " + "referables within the same name space shall be unique " + "(case-sensitive)." ) if not ( not (that.submodel_elements is not None) or ( not (that.kind_or_default() != aas_types.ModellingKind.TEMPLATE) or ( all( not (submodel_element.qualifiers is not None) or ( all( qualifier.kind_or_default() != aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in submodel_element.qualifiers ) ) for submodel_element in that.submodel_elements ) ) ) ): yield Error( "Constraint AASd-129: If any qualifier kind value of " + "a Submodel element qualifier (attribute qualifier inherited " + "via Qualifiable) is equal to Template Qualifier then " + "the submodel element shall be part of a submodel template, " + "i.e. a Submodel with submodel kind (attribute kind " + "inherited via Has-Kind) value is equal to Template." ) if not ( not (that.qualifiers is not None) or ( not ( any( qualifier.kind_or_default() == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModellingKind.TEMPLATE) ) ): yield Error( "Constraint AASd-119: If any qualifier kind value of " + "a qualifiable qualifier is equal to template qualifier and " + "the qualified element has kind then the qualified element " + "shall be of kind template." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.administration is not None: for error in self.transform(that.administration): error.path._prepend(PropertySegment(that, "administration")) yield error for error in verify_identifier(that.id): error.path._prepend(PropertySegment(that, "id")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.submodel_elements is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate( that.submodel_elements ): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.submodel_elements, i)) error.path._prepend(PropertySegment(that, "submodel_elements")) yield error # noinspection PyMethodMayBeStatic def transform_relationship_element( self, that: aas_types.RelationshipElement ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error for error in self.transform(that.first): error.path._prepend(PropertySegment(that, "first")) yield error for error in self.transform(that.second): error.path._prepend(PropertySegment(that, "second")) yield error # noinspection PyMethodMayBeStatic def transform_submodel_element_list( self, that: aas_types.SubmodelElementList ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.value is not None) or (len(that.value) >= 1)): yield Error("Value must be either not set or have at least one item.") if not ( not ( ( (that.value is not None) and (that.semantic_id_list_element is not None) ) ) or ( all( not (child.semantic_id is not None) or reference_key_values_equal( child.semantic_id, that.semantic_id_list_element ) for child in that.value ) ) ): yield Error( "Constraint AASd-107: If a first level child element has " + "a semantic ID it shall be identical to semantic ID list " + "element." ) if not ( not (that.value is not None) or submodel_elements_have_identical_semantic_ids(that.value) ): yield Error( "Constraint AASd-114: If two first level child elements have " + "a semantic ID then they shall be identical." ) if not ( not (that.value is not None) or ( all( submodel_element_is_of_type(element, that.type_value_list_element) for element in that.value ) ) ): yield Error( "Constraint AASd-108: All first level child elements shall " + "have the same submodel element type as specified in type " + "value list element." ) if not ( not ( ( that.type_value_list_element == aas_types.AASSubmodelElements.PROPERTY or that.type_value_list_element == aas_types.AASSubmodelElements.RANGE ) ) or ( ( (that.value_type_list_element is not None) and ( ( (that.value is None) or properties_or_ranges_have_value_type( that.value, that.value_type_list_element ) ) ) ) ) ): yield Error( "Constraint AASd-109: If type value list element is equal to " + "Property or Range value type list element shall be set and " + "all first level child elements shall have the value type as " + "specified in value type list element." ) if not ( not (that.value is not None) or (all(element.id_short is None for element in that.value)) ): yield Error( "Constraint AASd-120: ID-short of submodel elements being " + "a direct child of a Submodel element list shall not be " + "specified." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.semantic_id_list_element is not None: for error in self.transform(that.semantic_id_list_element): error.path._prepend(PropertySegment(that, "semantic_id_list_element")) yield error if that.value is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate(that.value): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.value, i)) error.path._prepend(PropertySegment(that, "value")) yield error # noinspection PyMethodMayBeStatic def transform_submodel_element_collection( self, that: aas_types.SubmodelElementCollection ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.value is not None) or (len(that.value) >= 1)): yield Error("Value must be either not set or have at least one item.") if not ( not (that.value is not None) or (all(item.id_short is not None for item in that.value)) ): yield Error( "ID-shorts need to be defined for all the items of value " + "according to AASd-117 (ID-short of Referables not being " + "a direct child of a Submodel element list shall be " + "specified)." ) if not (not (that.value is not None) or id_shorts_are_unique(that.value)): yield Error("ID-shorts of the value must be unique.") if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.value is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate(that.value): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.value, i)) error.path._prepend(PropertySegment(that, "value")) yield error # noinspection PyMethodMayBeStatic def transform_property(self, that: aas_types.Property) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_DATA_ELEMENT) ): yield Error( "Constraint AASd-090: For data elements category shall be " + "one of the following values: CONSTANT, PARAMETER or " + "VARIABLE." ) if not ( not (that.value is not None) or value_consistent_with_xsd_type(that.value, that.value_type) ): yield Error("Value must be consistent with the value type.") if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.value is not None: for error in verify_value_data_type(that.value): error.path._prepend(PropertySegment(that, "value")) yield error if that.value_id is not None: for error in self.transform(that.value_id): error.path._prepend(PropertySegment(that, "value_id")) yield error # noinspection PyMethodMayBeStatic def transform_multi_language_property( self, that: aas_types.MultiLanguageProperty ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_DATA_ELEMENT) ): yield Error( "Constraint AASd-090: For data elements category shall be " + "one of the following values: CONSTANT, PARAMETER or " + "VARIABLE." ) if not ( not (that.value is not None) or lang_strings_have_unique_languages(that.value) ): yield Error("Value must specify unique languages.") if not (not (that.value is not None) or (len(that.value) >= 1)): yield Error("Value must be either not set or have at least one item.") if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.value is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate(that.value): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.value, i)) error.path._prepend(PropertySegment(that, "value")) yield error if that.value_id is not None: for error in self.transform(that.value_id): error.path._prepend(PropertySegment(that, "value_id")) yield error # noinspection PyMethodMayBeStatic def transform_range(self, that: aas_types.Range) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_DATA_ELEMENT) ): yield Error( "Constraint AASd-090: For data elements category shall be " + "one of the following values: CONSTANT, PARAMETER or " + "VARIABLE." ) if not ( not (that.max is not None) or value_consistent_with_xsd_type(that.max, that.value_type) ): yield Error("Max must be consistent with the value type.") if not ( not (that.min is not None) or value_consistent_with_xsd_type(that.min, that.value_type) ): yield Error("Min must be consistent with the value type.") if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.min is not None: for error in verify_value_data_type(that.min): error.path._prepend(PropertySegment(that, "min")) yield error if that.max is not None: for error in verify_value_data_type(that.max): error.path._prepend(PropertySegment(that, "max")) yield error # noinspection PyMethodMayBeStatic def transform_reference_element( self, that: aas_types.ReferenceElement ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_DATA_ELEMENT) ): yield Error( "Constraint AASd-090: For data elements category shall be " + "one of the following values: CONSTANT, PARAMETER or " + "VARIABLE." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.value is not None: for error in self.transform(that.value): error.path._prepend(PropertySegment(that, "value")) yield error # noinspection PyMethodMayBeStatic def transform_blob(self, that: aas_types.Blob) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_DATA_ELEMENT) ): yield Error( "Constraint AASd-090: For data elements category shall be " + "one of the following values: CONSTANT, PARAMETER or " + "VARIABLE." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.value is not None: for error in verify_blob_type(that.value): error.path._prepend(PropertySegment(that, "value")) yield error for error in verify_content_type(that.content_type): error.path._prepend(PropertySegment(that, "content_type")) yield error # noinspection PyMethodMayBeStatic def transform_file(self, that: aas_types.File) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_DATA_ELEMENT) ): yield Error( "Constraint AASd-090: For data elements category shall be " + "one of the following values: CONSTANT, PARAMETER or " + "VARIABLE." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.value is not None: for error in verify_path_type(that.value): error.path._prepend(PropertySegment(that, "value")) yield error for error in verify_content_type(that.content_type): error.path._prepend(PropertySegment(that, "content_type")) yield error # noinspection PyMethodMayBeStatic def transform_annotated_relationship_element( self, that: aas_types.AnnotatedRelationshipElement ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.annotations is not None) or (len(that.annotations) >= 1)): yield Error( "Annotations must be either not set or have at least one " + "item." ) if not ( not (that.annotations is not None) or (all(item.id_short is not None for item in that.annotations)) ): yield Error( "ID-shorts need to be defined for all the items of " + "annotations according to AASd-117 (ID-short of Referables " + "not being a direct child of a Submodel element list shall " + "be specified)." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error for error in self.transform(that.first): error.path._prepend(PropertySegment(that, "first")) yield error for error in self.transform(that.second): error.path._prepend(PropertySegment(that, "second")) yield error if that.annotations is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate(that.annotations): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.annotations, i)) error.path._prepend(PropertySegment(that, "annotations")) yield error # noinspection PyMethodMayBeStatic def transform_entity(self, that: aas_types.Entity) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.statements is not None) or (len(that.statements) >= 1)): yield Error("Statements must be either not set or have at least one item.") if not ( not (that.statements is not None) or (all(item.id_short is not None for item in that.statements)) ): yield Error( "ID-shorts need to be defined for all the items of " + "statements according to AASd-117 (ID-short of Referables " + "not being a direct child of a Submodel element list shall " + "be specified)." ) if not ( ( ( ( that.entity_type == aas_types.EntityType.SELF_MANAGED_ENTITY and ( ( ( ( (that.global_asset_id is not None) and (that.specific_asset_ids is None) ) ) or ( ( (that.global_asset_id is None) and (that.specific_asset_ids is not None) and len(that.specific_asset_ids) >= 1 ) ) ) ) ) ) or ( ( that.entity_type != aas_types.EntityType.SELF_MANAGED_ENTITY and (that.global_asset_id is None) and (that.specific_asset_ids is None) ) ) ) ): yield Error( "Constraint AASd-014: Either the attribute global asset ID " + "or specific asset ID must be set if entity type is set to " + "self-managed entity. They are not existing otherwise." ) if not ( not (that.specific_asset_ids is not None) or (len(that.specific_asset_ids) >= 1) ): yield Error( "Specific asset IDs must be either not set or have at least " + "one item." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.statements is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate(that.statements): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.statements, i)) error.path._prepend(PropertySegment(that, "statements")) yield error if that.global_asset_id is not None: for error in verify_identifier(that.global_asset_id): error.path._prepend(PropertySegment(that, "global_asset_id")) yield error if that.specific_asset_ids is not None: for i, yet_yet_yet_yet_yet_yet_another_item in enumerate( that.specific_asset_ids ): for error in self.transform(yet_yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.specific_asset_ids, i)) error.path._prepend(PropertySegment(that, "specific_asset_ids")) yield error # noinspection PyMethodMayBeStatic def transform_event_payload(self, that: aas_types.EventPayload) -> Iterator[Error]: if not ( ( is_model_reference_to(that.source, aas_types.KeyTypes.EVENT_ELEMENT) or is_model_reference_to( that.source, aas_types.KeyTypes.BASIC_EVENT_ELEMENT ) ) ): yield Error("Source must be a model reference to an Event element.") if not (is_model_reference_to_referable(that.observable_reference)): yield Error( "Observable reference must be a model reference to " + "a referable." ) for error in self.transform(that.source): error.path._prepend(PropertySegment(that, "source")) yield error if that.source_semantic_id is not None: for error in self.transform(that.source_semantic_id): error.path._prepend(PropertySegment(that, "source_semantic_id")) yield error for error in self.transform(that.observable_reference): error.path._prepend(PropertySegment(that, "observable_reference")) yield error if that.observable_semantic_id is not None: for error in self.transform(that.observable_semantic_id): error.path._prepend(PropertySegment(that, "observable_semantic_id")) yield error if that.topic is not None: for error in verify_message_topic_type(that.topic): error.path._prepend(PropertySegment(that, "topic")) yield error if that.subject_id is not None: for error in self.transform(that.subject_id): error.path._prepend(PropertySegment(that, "subject_id")) yield error for error in verify_date_time_utc(that.time_stamp): error.path._prepend(PropertySegment(that, "time_stamp")) yield error if that.payload is not None: for error in verify_blob_type(that.payload): error.path._prepend(PropertySegment(that, "payload")) yield error # noinspection PyMethodMayBeStatic def transform_basic_event_element( self, that: aas_types.BasicEventElement ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( not (that.direction == aas_types.Direction.INPUT) or (that.max_interval is None) ): yield Error("Max. interval is not applicable for input direction.") if not is_model_reference_to_referable(that.observed): yield Error("Observed must be a model reference to a referable.") if not ( not (that.message_broker is not None) or is_model_reference_to_referable(that.message_broker) ): yield Error("Message broker must be a model reference to a referable.") if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error for error in self.transform(that.observed): error.path._prepend(PropertySegment(that, "observed")) yield error if that.message_topic is not None: for error in verify_message_topic_type(that.message_topic): error.path._prepend(PropertySegment(that, "message_topic")) yield error if that.message_broker is not None: for error in self.transform(that.message_broker): error.path._prepend(PropertySegment(that, "message_broker")) yield error if that.last_update is not None: for error in verify_date_time_utc(that.last_update): error.path._prepend(PropertySegment(that, "last_update")) yield error if that.min_interval is not None: for error in verify_duration(that.min_interval): error.path._prepend(PropertySegment(that, "min_interval")) yield error if that.max_interval is not None: for error in verify_duration(that.max_interval): error.path._prepend(PropertySegment(that, "max_interval")) yield error # noinspection PyMethodMayBeStatic def transform_operation(self, that: aas_types.Operation) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not ( id_shorts_of_variables_are_unique( that.input_variables, that.output_variables, that.inoutput_variables ) ): yield Error( "Constraint AASd-134: For an Operation the ID-short of all " + "values of input, output and in/output variables shall be " + "unique." ) if not ( not (that.input_variables is not None) or (len(that.input_variables) >= 1) ): yield Error( "Input variables must be either not set or have at least one " + "item." ) if not ( not (that.output_variables is not None) or (len(that.output_variables) >= 1) ): yield Error( "Output variables must be either not set or have at least " + "one item." ) if not ( not (that.inoutput_variables is not None) or (len(that.inoutput_variables) >= 1) ): yield Error( "Inoutput variables must be either not set or have at least " + "one item." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.input_variables is not None: for i, yet_yet_yet_yet_yet_another_item in enumerate(that.input_variables): for error in self.transform(yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.input_variables, i)) error.path._prepend(PropertySegment(that, "input_variables")) yield error if that.output_variables is not None: for i, yet_yet_yet_yet_yet_yet_another_item in enumerate( that.output_variables ): for error in self.transform(yet_yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.output_variables, i)) error.path._prepend(PropertySegment(that, "output_variables")) yield error if that.inoutput_variables is not None: for i, yet_yet_yet_yet_yet_yet_yet_another_item in enumerate( that.inoutput_variables ): for error in self.transform(yet_yet_yet_yet_yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.inoutput_variables, i)) error.path._prepend(PropertySegment(that, "inoutput_variables")) yield error # noinspection PyMethodMayBeStatic def transform_operation_variable( self, that: aas_types.OperationVariable ) -> Iterator[Error]: if not (that.value.id_short is not None): yield Error( "Value must have the ID-short specified according to " + "Constraint AASd-117 (ID-short of Referables not being " + "a direct child of a Submodel element list shall be " + "specified)." ) for error in self.transform(that.value): error.path._prepend(PropertySegment(that, "value")) yield error # noinspection PyMethodMayBeStatic def transform_capability(self, that: aas_types.Capability) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.supplemental_semantic_ids is not None) or (len(that.supplemental_semantic_ids) >= 1) ): yield Error( "Supplemental semantic IDs must be either not set or have at " + "least one item." ) if not ( not (that.supplemental_semantic_ids is not None) or (that.semantic_id is not None) ): yield Error( "Constraint AASd-118: If there are supplemental semantic IDs " + "defined then there shall be also a main semantic ID." ) if not (not (that.qualifiers is not None) or (len(that.qualifiers) >= 1)): yield Error("Qualifiers must be either not set or have at least one item.") if not ( not (that.qualifiers is not None) or qualifier_types_are_unique(that.qualifiers) ): yield Error( "Constraint AASd-021: Every qualifiable can only have one " + "qualifier with the same type." ) if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.semantic_id is not None: for error in self.transform(that.semantic_id): error.path._prepend(PropertySegment(that, "semantic_id")) yield error if that.supplemental_semantic_ids is not None: for i, yet_yet_another_item in enumerate(that.supplemental_semantic_ids): for error in self.transform(yet_yet_another_item): error.path._prepend(IndexSegment(that.supplemental_semantic_ids, i)) error.path._prepend( PropertySegment(that, "supplemental_semantic_ids") ) yield error if that.qualifiers is not None: for i, yet_yet_yet_another_item in enumerate(that.qualifiers): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.qualifiers, i)) error.path._prepend(PropertySegment(that, "qualifiers")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_yet_yet_another_item in enumerate( that.embedded_data_specifications ): for error in self.transform(yet_yet_yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error # noinspection PyMethodMayBeStatic def transform_concept_description( self, that: aas_types.ConceptDescription ) -> Iterator[Error]: if not (not (that.extensions is not None) or (len(that.extensions) >= 1)): yield Error("Extensions must be either not set or have at least one item.") if not ( not (that.extensions is not None) or extension_names_are_unique(that.extensions) ): yield Error( "Constraint AASd-077: The name of an extension within " + "Has-Extensions needs to be unique." ) if not (not (that.description is not None) or (len(that.description) >= 1)): yield Error( "Description must be either not set or have at least one " + "item." ) if not ( not (that.description is not None) or lang_strings_have_unique_languages(that.description) ): yield Error("Description must specify unique languages.") if not (not (that.display_name is not None) or (len(that.display_name) >= 1)): yield Error( "Display name must be either not set or have at least one " + "item." ) if not ( not (that.display_name is not None) or lang_strings_have_unique_languages(that.display_name) ): yield Error("Display name must specify unique languages.") if not ( not (that.embedded_data_specifications is not None) or (len(that.embedded_data_specifications) >= 1) ): yield Error( "Embedded data specifications must be either not set or have " + "at least one item." ) if not (not (that.is_case_of is not None) or (len(that.is_case_of) >= 1)): yield Error("Is-case-of must be either not set or have at least one item.") if not ( not (that.embedded_data_specifications is not None) or ( ( data_specification_iec_61360s_have_definition_at_least_in_english( that.embedded_data_specifications ) or data_specification_iec_61360s_have_value( that.embedded_data_specifications ) ) ) ): yield Error( "Constraint AASc-3a-008: For a concept description using " + "data specification template IEC 61360, the definition is " + "mandatory and shall be defined at least in English. " + "Exception: The concept description describes a value." ) if not ( not ( ( (that.category is not None) and that.category == "QUALIFIER_TYPE" and (that.embedded_data_specifications is not None) ) ) or data_specification_iec_61360s_have_data_type( that.embedded_data_specifications ) ): yield Error( "Constraint AASc-3a-007: For a concept description with " + "category QUALIFIER_TYPE using data specification IEC 61360, " + "the data type of the data specification is mandatory and " + "shall be defined." ) if not ( not ( ( (that.category is not None) and that.category == "DOCUMENT" and (that.embedded_data_specifications is not None) ) ) or data_specification_iec_61360s_for_document_have_appropriate_data_type( that.embedded_data_specifications ) ): yield Error( "Constraint AASc-3a-006: For a concept description with " + "category DOCUMENT using data specification IEC 61360, " + "the data type of the data specification shall be one of: " + "FILE, BLOB, HTML." ) if not ( not ( ( (that.category is not None) and that.category == "REFERENCE" and (that.embedded_data_specifications is not None) ) ) or data_specification_iec_61360s_for_reference_have_appropriate_data_type( that.embedded_data_specifications ) ): yield Error( "Constraint AASc-3a-005: For a concept description with " + "category REFERENCE using data specification IEC 61360, " + "the data type of the data specification shall be one of: " + "STRING, IRI, IRDI." ) if not ( not ( ( (that.category is not None) and ((that.category == "PROPERTY" or that.category == "VALUE")) and (that.embedded_data_specifications is not None) ) ) or data_specification_iec_61360s_for_property_or_value_have_appropriate_data_type( that.embedded_data_specifications ) ): yield Error( "Constraint AASc-3a-004: For a concept description with " + "category PROPERTY or VALUE using data specification IEC " + "61360, the data type of the data specification is mandatory " + "and shall be one of: DATE, STRING, STRING_TRANSLATABLE, " + "INTEGER_MEASURE, INTEGER_COUNT, INTEGER_CURRENCY, " + "REAL_MEASURE, REAL_COUNT, REAL_CURRENCY, BOOLEAN, RATIONAL, " + "RATIONAL_MEASURE, TIME, TIMESTAMP." ) if that.extensions is not None: for i, an_item in enumerate(that.extensions): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.extensions, i)) error.path._prepend(PropertySegment(that, "extensions")) yield error if that.category is not None: for error in verify_name_type(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short_type(that.id_short): error.path._prepend(PropertySegment(that, "id_short")) yield error if that.display_name is not None: for i, another_item in enumerate(that.display_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.display_name, i)) error.path._prepend(PropertySegment(that, "display_name")) yield error if that.description is not None: for i, yet_another_item in enumerate(that.description): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.description, i)) error.path._prepend(PropertySegment(that, "description")) yield error if that.administration is not None: for error in self.transform(that.administration): error.path._prepend(PropertySegment(that, "administration")) yield error for error in verify_identifier(that.id): error.path._prepend(PropertySegment(that, "id")) yield error if that.embedded_data_specifications is not None: for i, yet_yet_another_item in enumerate(that.embedded_data_specifications): for error in self.transform(yet_yet_another_item): error.path._prepend( IndexSegment(that.embedded_data_specifications, i) ) error.path._prepend( PropertySegment(that, "embedded_data_specifications") ) yield error if that.is_case_of is not None: for i, yet_yet_yet_another_item in enumerate(that.is_case_of): for error in self.transform(yet_yet_yet_another_item): error.path._prepend(IndexSegment(that.is_case_of, i)) error.path._prepend(PropertySegment(that, "is_case_of")) yield error # noinspection PyMethodMayBeStatic def transform_reference(self, that: aas_types.Reference) -> Iterator[Error]: if not (len(that.keys) >= 1): yield Error("Keys must contain at least one item.") if not ( not (len(that.keys) >= 1) or (that.keys[0].type in aas_constants.GLOBALLY_IDENTIFIABLES) ): yield Error( "Constraint AASd-121: For References the value of type of " + "the first key of keys shall be one of Globally " + "Identifiables." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.EXTERNAL_REFERENCE and len(that.keys) >= 1 ) ) or (that.keys[0].type in aas_constants.GENERIC_GLOBALLY_IDENTIFIABLES) ): yield Error( "Constraint AASd-122: For external references the value of " + "type of the first key of keys shall be one of Generic " + "Globally Identifiables." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(that.keys) >= 1 ) ) or (that.keys[0].type in aas_constants.AAS_IDENTIFIABLES) ): yield Error( "Constraint AASd-123: For model references the value of type " + "of the first key of keys shall be one of AAS identifiables." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.EXTERNAL_REFERENCE and len(that.keys) >= 1 ) ) or ( ( (that.keys[-1].type in aas_constants.GENERIC_GLOBALLY_IDENTIFIABLES) or (that.keys[-1].type in aas_constants.GENERIC_FRAGMENT_KEYS) ) ) ): yield Error( "Constraint AASd-124: For external references the last key " + "of keys shall be either one of Generic Globally " + "Identifiables or one of Generic Fragment Keys." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(that.keys) > 1 ) ) or ( all( that.keys[i].type in aas_constants.FRAGMENT_KEYS for i in range(1, len(that.keys)) ) ) ): yield Error( "Constraint AASd-125: For model references with more than " + "one key in keys the value of type of each of the keys " + "following the first key of keys shall be one of Fragment " + "Keys." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(that.keys) > 1 ) ) or ( all( not (that.keys[i].type in aas_constants.GENERIC_FRAGMENT_KEYS) for i in range(0, len(that.keys) - 1) ) ) ): yield Error( "Constraint AASd-126: For model references with more than " + "one key in keys the value of type of the last key in " + "the reference key chain may be one of Generic Fragment Keys " + "or no key at all shall have a value out of Generic Fragment " + "Keys." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(that.keys) > 1 and that.keys[-1].type == aas_types.KeyTypes.FRAGMENT_REFERENCE ) ) or ( ( that.keys[-2].type == aas_types.KeyTypes.FILE or that.keys[-2].type == aas_types.KeyTypes.BLOB ) ) ): yield Error( "Constraint AASd-127: For model references, with more than " + "one key in keys a key with type Fragment Reference shall be " + "preceded by a key with type File or Blob." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.MODEL_REFERENCE and len(that.keys) > 2 ) ) or ( all( not (that.keys[i].type == aas_types.KeyTypes.SUBMODEL_ELEMENT_LIST) or matches_xs_non_negative_integer(that.keys[i + 1].value) for i in range(0, len(that.keys) - 1) ) ) ): yield Error( "Constraint AASd-128: For model references, the value of " + "a key preceded by a key with type Submodel element list is " + "an integer number denoting the position in the array of " + "the submodel element list." ) if that.referred_semantic_id is not None: for error in self.transform(that.referred_semantic_id): error.path._prepend(PropertySegment(that, "referred_semantic_id")) yield error for i, an_item in enumerate(that.keys): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.keys, i)) error.path._prepend(PropertySegment(that, "keys")) yield error # noinspection PyMethodMayBeStatic def transform_key(self, that: aas_types.Key) -> Iterator[Error]: for error in verify_identifier(that.value): error.path._prepend(PropertySegment(that, "value")) yield error # noinspection PyMethodMayBeStatic def transform_lang_string_name_type( self, that: aas_types.LangStringNameType ) -> Iterator[Error]: if not (len(that.text) <= 128): yield Error("String shall have a maximum length of 128 characters.") for error in verify_bcp_47_language_tag(that.language): error.path._prepend(PropertySegment(that, "language")) yield error for error in verify_non_empty_xml_serializable_string(that.text): error.path._prepend(PropertySegment(that, "text")) yield error # noinspection PyMethodMayBeStatic def transform_lang_string_text_type( self, that: aas_types.LangStringTextType ) -> Iterator[Error]: if not (len(that.text) <= 1023): yield Error("String shall have a maximum length of 1023 characters.") for error in verify_bcp_47_language_tag(that.language): error.path._prepend(PropertySegment(that, "language")) yield error for error in verify_non_empty_xml_serializable_string(that.text): error.path._prepend(PropertySegment(that, "text")) yield error # noinspection PyMethodMayBeStatic def transform_environment(self, that: aas_types.Environment) -> Iterator[Error]: if not ( not (that.concept_descriptions is not None) or (len(that.concept_descriptions) >= 1) ): yield Error( "Concept descriptions must be either not set or have at " + "least one item." ) if not (not (that.submodels is not None) or (len(that.submodels) >= 1)): yield Error("Submodels must be either not set or have at least one item.") if not ( not (that.asset_administration_shells is not None) or (len(that.asset_administration_shells) >= 1) ): yield Error( "Asset administration shells must be either not set or have " + "at least one item." ) if that.asset_administration_shells is not None: for i, an_item in enumerate(that.asset_administration_shells): for error in self.transform(an_item): error.path._prepend( IndexSegment(that.asset_administration_shells, i) ) error.path._prepend( PropertySegment(that, "asset_administration_shells") ) yield error if that.submodels is not None: for i, another_item in enumerate(that.submodels): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.submodels, i)) error.path._prepend(PropertySegment(that, "submodels")) yield error if that.concept_descriptions is not None: for i, yet_another_item in enumerate(that.concept_descriptions): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.concept_descriptions, i)) error.path._prepend(PropertySegment(that, "concept_descriptions")) yield error # noinspection PyMethodMayBeStatic def transform_embedded_data_specification( self, that: aas_types.EmbeddedDataSpecification ) -> Iterator[Error]: for error in self.transform(that.data_specification): error.path._prepend(PropertySegment(that, "data_specification")) yield error for error in self.transform(that.data_specification_content): error.path._prepend(PropertySegment(that, "data_specification_content")) yield error # noinspection PyMethodMayBeStatic def transform_level_type(self, that: aas_types.LevelType) -> Iterator[Error]: # No verification has been defined for LevelType. return # For this uncommon return-yield construction, see: # https://stackoverflow.com/questions/13243766/how-to-define-an-empty-generator-function # noinspection PyUnreachableCode yield # noinspection PyMethodMayBeStatic def transform_value_reference_pair( self, that: aas_types.ValueReferencePair ) -> Iterator[Error]: for error in verify_value_type_iec_61360(that.value): error.path._prepend(PropertySegment(that, "value")) yield error for error in self.transform(that.value_id): error.path._prepend(PropertySegment(that, "value_id")) yield error # noinspection PyMethodMayBeStatic def transform_value_list(self, that: aas_types.ValueList) -> Iterator[Error]: if not (len(that.value_reference_pairs) >= 1): yield Error("Value reference pair types must contain at least one item.") for i, an_item in enumerate(that.value_reference_pairs): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.value_reference_pairs, i)) error.path._prepend(PropertySegment(that, "value_reference_pairs")) yield error # noinspection PyMethodMayBeStatic def transform_lang_string_preferred_name_type_iec_61360( self, that: aas_types.LangStringPreferredNameTypeIEC61360 ) -> Iterator[Error]: if not (len(that.text) <= 255): yield Error("String shall have a maximum length of 255 characters.") for error in verify_bcp_47_language_tag(that.language): error.path._prepend(PropertySegment(that, "language")) yield error for error in verify_non_empty_xml_serializable_string(that.text): error.path._prepend(PropertySegment(that, "text")) yield error # noinspection PyMethodMayBeStatic def transform_lang_string_short_name_type_iec_61360( self, that: aas_types.LangStringShortNameTypeIEC61360 ) -> Iterator[Error]: if not (len(that.text) <= 18): yield Error("String shall have a maximum length of 18 characters.") for error in verify_bcp_47_language_tag(that.language): error.path._prepend(PropertySegment(that, "language")) yield error for error in verify_non_empty_xml_serializable_string(that.text): error.path._prepend(PropertySegment(that, "text")) yield error # noinspection PyMethodMayBeStatic def transform_lang_string_definition_type_iec_61360( self, that: aas_types.LangStringDefinitionTypeIEC61360 ) -> Iterator[Error]: if not (len(that.text) <= 1023): yield Error("String shall have a maximum length of 1023 characters.") for error in verify_bcp_47_language_tag(that.language): error.path._prepend(PropertySegment(that, "language")) yield error for error in verify_non_empty_xml_serializable_string(that.text): error.path._prepend(PropertySegment(that, "text")) yield error # noinspection PyMethodMayBeStatic def transform_data_specification_iec_61360( self, that: aas_types.DataSpecificationIEC61360 ) -> Iterator[Error]: if not (not (((that.value is not None) and (that.value_list is not None)))): yield Error( "Constraint AASc-3a-010: If value is not empty then value " + "list shall be empty and vice versa." ) if not ( not ( ( (that.data_type is not None) and (that.data_type in aas_constants.IEC_61360_DATA_TYPES_WITH_UNIT) ) ) or (((that.unit is not None) or (that.unit_id is not None))) ): yield Error( "Constraint AASc-3a-009: If data type is a an integer, real " + "or rational with a measure or currency, unit or unit ID " + "shall be defined." ) if not (not (that.definition is not None) or (len(that.definition) >= 1)): yield Error("Definition must be either not set or have at least one item.") if not ( not (that.definition is not None) or lang_strings_have_unique_languages(that.definition) ): yield Error("Definition must specify unique languages.") if not (not (that.short_name is not None) or (len(that.short_name) >= 1)): yield Error("Short name must be either not set or have at least one item.") if not ( not (that.short_name is not None) or lang_strings_have_unique_languages(that.short_name) ): yield Error("Short name must specify unique languages.") if not (len(that.preferred_name) >= 1): yield Error("Preferred name must have at least one item.") if not (lang_strings_have_unique_languages(that.preferred_name)): yield Error("Preferred name must specify unique languages.") if not ( any( is_bcp_47_for_english(lang_string.language) for lang_string in that.preferred_name ) ): yield Error( "Constraint AASc-3a-002: preferred name shall be provided at " + "least in English." ) for i, an_item in enumerate(that.preferred_name): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.preferred_name, i)) error.path._prepend(PropertySegment(that, "preferred_name")) yield error if that.short_name is not None: for i, another_item in enumerate(that.short_name): for error in self.transform(another_item): error.path._prepend(IndexSegment(that.short_name, i)) error.path._prepend(PropertySegment(that, "short_name")) yield error if that.unit is not None: for error in verify_non_empty_xml_serializable_string(that.unit): error.path._prepend(PropertySegment(that, "unit")) yield error if that.unit_id is not None: for error in self.transform(that.unit_id): error.path._prepend(PropertySegment(that, "unit_id")) yield error if that.source_of_definition is not None: for error in verify_non_empty_xml_serializable_string( that.source_of_definition ): error.path._prepend(PropertySegment(that, "source_of_definition")) yield error if that.symbol is not None: for error in verify_non_empty_xml_serializable_string(that.symbol): error.path._prepend(PropertySegment(that, "symbol")) yield error if that.definition is not None: for i, yet_another_item in enumerate(that.definition): for error in self.transform(yet_another_item): error.path._prepend(IndexSegment(that.definition, i)) error.path._prepend(PropertySegment(that, "definition")) yield error if that.value_format is not None: for error in verify_non_empty_xml_serializable_string(that.value_format): error.path._prepend(PropertySegment(that, "value_format")) yield error if that.value_list is not None: for error in self.transform(that.value_list): error.path._prepend(PropertySegment(that, "value_list")) yield error if that.value is not None: for error in verify_value_type_iec_61360(that.value): error.path._prepend(PropertySegment(that, "value")) yield error if that.level_type is not None: for error in self.transform(that.level_type): error.path._prepend(PropertySegment(that, "level_type")) yield error _TRANSFORMER = _Transformer()
[docs]def verify(that: aas_types.Class) -> Iterator[Error]: """ Verify the constraints of :paramref:`that` recursively. :param that: instance whose constraints we want to verify :yield: constraint violations """ yield from _TRANSFORMER.transform(that)
[docs]def verify_xml_serializable_string(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." )
[docs]def verify_non_empty_xml_serializable_string(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.")
[docs]def verify_date_time_utc(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xs_date_time_utc(that): yield Error( "The value must match the pattern of xs:dateTime with " + "the time zone fixed to UTC." ) if not is_xs_date_time_utc(that): yield Error( "The value must represent a valid xs:dateTime with the time " + "zone fixed to UTC." )
[docs]def verify_duration(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xs_duration(that): yield Error("The value must match the pattern of xs:duration.")
# noinspection PyUnusedLocal
[docs]def verify_blob_type(that: bytes) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" # There is no verification specified. return # Empty generator according to: # https://stackoverflow.com/a/13243870/1600678 # noinspection PyUnreachableCode yield
[docs]def verify_identifier(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 2000): yield Error("Identifier shall have a maximum length of 2000 characters.")
[docs]def verify_value_type_iec_61360(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 2000): yield Error( "Value type IEC 61360 shall have a maximum length of 2000 " + "characters." )
[docs]def verify_name_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 128): yield Error("Name type shall have a maximum length of 128 characters.")
[docs]def verify_version_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not matches_version_type(that): yield Error("Version type shall match the version pattern.") if not (len(that) <= 4): yield Error("Version type shall have a maximum length of 4 characters.")
[docs]def verify_revision_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not matches_revision_type(that): yield Error("Revision type shall match the revision pattern.") if not (len(that) <= 4): yield Error("Revision type shall have a maximum length of 4 characters.")
[docs]def verify_label_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 64): yield Error("Label type shall have a maximum length of 64 characters.")
[docs]def verify_message_topic_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 255): yield Error( "Message topic type shall have a maximum length of 255 " + "characters." )
[docs]def verify_bcp_47_language_tag(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_bcp_47(that): yield Error( "The value must represent a value language tag conformant to " + "BCP 47." )
[docs]def verify_content_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 100): yield Error("Content type shall have a maximum length of 100 characters.") if not matches_mime_type(that): yield Error( "The value must represent a valid content MIME type " + "according to RFC 2046." )
[docs]def verify_path_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 2000): yield Error("Identifier shall have a maximum length of 2000 characters.") if not matches_rfc_2396(that): yield Error( "String with max 2048 and min 1 characters conformant to " + "a URI as per RFC 2396." )
[docs]def verify_qualifier_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 128): yield Error("Name type shall have a maximum length of 128 characters.")
[docs]def verify_value_data_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." )
[docs]def verify_id_short_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xml_serializable_string(that): yield Error( "Constraint AASd-130: An attribute with data type 'string' " + "shall consist of these characters only: " + "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$." ) if not (len(that) >= 1): yield Error("The value must not be empty.") if not (len(that) <= 128): yield Error("Name type shall have a maximum length of 128 characters.") if not matches_id_short(that): yield Error( "ID-short of Referables shall only feature letters, digits, " + "underscore (``_``); starting mandatory with a letter. " + "*I.e.* ``[a-zA-Z][a-zA-Z0-9_]*``." )
# This code has been automatically generated by aas-core-codegen. # Do NOT edit or append.