Source code for aas_core3_rc02.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_rc02.types.Extension`:

.. code-block::

    import aas_core3_rc02.types as aas_types
    import aas_core3_rc02.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_rc02 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()
# 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_xs_date_time_stamp_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" date_time_stamp_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_stamp_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DATE_TIME_STAMP_UTC = _construct_matches_xs_date_time_stamp_utc()
[docs]def matches_xs_date_time_stamp_utc(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:dateTimeStamp``. 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/xmlschema11-2/#dateTimeStamp :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DATE_TIME_STAMP_UTC.match(text) is not None
[docs]def is_xs_date_time_stamp_utc(value: str) -> bool: """ Check that :paramref:`value` is a ``xs:dateTimeStamp`` with the time zone set to UTC. """ if not matches_xs_date_time_stamp_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_8089_path() -> Pattern[str]: 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}:){{2}}{h16})?::({h16}:){{2}}{ls32}|(({h16}:){{3}}{h16})?::{h16}:{ls32}|(({h16}:){{4}}{h16})?::{ls32}|(({h16}:){{5}}{h16})?::{h16}|(({h16}:){{6}}{h16})?::)" unreserved = "[a-zA-Z0-9\\-._~]" sub_delims = "[!$&'()*+,;=]" ipvfuture = f"[vV][0-9A-Fa-f]+\\.({unreserved}|{sub_delims}|:)+" ip_literal = f"\\[({ipv6address}|{ipvfuture})\\]" pct_encoded = "%[0-9A-Fa-f][0-9A-Fa-f]" reg_name = f"({unreserved}|{pct_encoded}|{sub_delims})*" host = f"({ip_literal}|{ipv4address}|{reg_name})" file_auth = f"(localhost|{host})" pchar = f"({unreserved}|{pct_encoded}|{sub_delims}|[:@])" segment_nz = f"({pchar})+" segment = f"({pchar})*" path_absolute = f"/({segment_nz}(/{segment})*)?" auth_path = f"({file_auth})?{path_absolute}" local_path = f"{path_absolute}" file_hier_part = f"(//{auth_path}|{local_path})" file_scheme = "file" file_uri = f"{file_scheme}:{file_hier_part}" pattern = f"^{file_uri}$" return re.compile(pattern) _REGEX_MATCHES_RFC_8089_PATH = _construct_matches_rfc_8089_path()
[docs]def matches_rfc_8089_path(text: str) -> bool: """ Check that :paramref:`text` is a path conforming to the pattern of RFC 8089. The definition has been taken from: https://datatracker.ietf.org/doc/html/rfc8089 :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_RFC_8089_PATH.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}){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.LangString], ) -> 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_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}:){{2}}{h16})?::({h16}:){{2}}{ls32}|(({h16}:){{3}}{h16})?::{h16}:{ls32}|(({h16}:){{4}}{h16})?::{ls32}|(({h16}:){{5}}{h16})?::{h16}|(({h16}:){{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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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
# noinspection SpellCheckingInspection def _construct_matches_xs_date_time_stamp() -> 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_stamp_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_stamp_lexical_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DATE_TIME_STAMP = _construct_matches_xs_date_time_stamp()
[docs]def matches_xs_date_time_stamp(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:dateTimeStamp``. See: https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DATE_TIME_STAMP.match(text) is not None
# 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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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_day_time_duration() -> Pattern[str]: day_time_duration_rep = "-?P((([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"^{day_time_duration_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_DAY_TIME_DURATION = _construct_matches_xs_day_time_duration()
[docs]def matches_xs_day_time_duration(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:dayTimeDuration``. See: https://www.w3.org/TR/xmlschema11-2/#dayTimeDuration :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_DAY_TIME_DURATION.match(text) is not None
# noinspection SpellCheckingInspection def _construct_matches_xs_year_month_duration() -> Pattern[str]: year_month_duration_rep = "-?P((([0-9]+Y)([0-9]+M)?)|([0-9]+M))" pattern = f"^{year_month_duration_rep}$" return re.compile(pattern) _REGEX_MATCHES_XS_YEAR_MONTH_DURATION = _construct_matches_xs_year_month_duration()
[docs]def matches_xs_year_month_duration(text: str) -> bool: """ Check that :paramref:`text` conforms to the pattern of an ``xs:yearMonthDuration``. See: https://www.w3.org/TR/xmlschema11-2/#yearMonthDuration :param text: Text to be checked :return: True if the :paramref:`text` conforms to the pattern """ return _REGEX_MATCHES_XS_YEAR_MONTH_DURATION.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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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/xmlschema11-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 = "^[\\x01-\\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/xmlschema11-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_date_time(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:dateTime``.""" # 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``). if not matches_xs_date_time(value): return False date, _ = value.split("T") return is_xs_date(date)
[docs]def is_xs_date_time_stamp(value: str) -> bool: """Check that :paramref:`value` is a valid ``xs:dateTimeStamp``.""" if not matches_xs_date_time_stamp(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``). date, _ = value.split("T") return is_xs_date(date)
[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.DATE: is_xs_date, aas_types.DataTypeDefXsd.DATE_TIME: is_xs_date_time, aas_types.DataTypeDefXsd.DATE_TIME_STAMP: is_xs_date_time_stamp, 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.STRING: matches_xs_string, aas_types.DataTypeDefXsd.TIME: matches_xs_time, aas_types.DataTypeDefXsd.DAY_TIME_DURATION: matches_xs_day_time_duration, aas_types.DataTypeDefXsd.YEAR_MONTH_DURATION: matches_xs_year_month_duration, aas_types.DataTypeDefXsd.INTEGER: matches_xs_integer, aas_types.DataTypeDefXsd.LONG: is_xs_long, aas_types.DataTypeDefXsd.INT: is_xs_int, aas_types.DataTypeDefXsd.SHORT: is_xs_short, aas_types.DataTypeDefXsd.BYTE: is_xs_byte, aas_types.DataTypeDefXsd.NON_NEGATIVE_INTEGER: matches_xs_non_negative_integer, aas_types.DataTypeDefXsd.POSITIVE_INTEGER: matches_xs_positive_integer, aas_types.DataTypeDefXsd.UNSIGNED_LONG: is_xs_unsigned_long, aas_types.DataTypeDefXsd.UNSIGNED_INT: is_xs_unsigned_int, aas_types.DataTypeDefXsd.UNSIGNED_SHORT: is_xs_unsigned_short, aas_types.DataTypeDefXsd.UNSIGNED_BYTE: is_xs_unsigned_byte, aas_types.DataTypeDefXsd.NON_POSITIVE_INTEGER: matches_xs_non_positive_integer, aas_types.DataTypeDefXsd.NEGATIVE_INTEGER: matches_xs_negative_integer, } 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)
# noinspection SpellCheckingInspection def _construct_matches_global_asset_id_literally() -> Pattern[str]: pattern = "^[gG][lL][oO][bB][aA][lL][aA][sS][sS][eE][tT][iI][dD]$" return re.compile(pattern) _REGEX_MATCHES_GLOBAL_ASSET_ID_LITERALLY = ( _construct_matches_global_asset_id_literally() )
[docs]def matches_global_asset_id_literally(text: str) -> bool: """ Check that the :paramref:`text` matches ``globalAssetId`` case-insensitive. The case-insensitivity depends on the culture. For example in Turkish, uppercase "i" is "İ", not "I". We assume the culture to be English, and explicitly check for English case-folding. :param text: which needs to match ``globalAssetId`` literally :return: True if the :paramref:`text` matches case-insensitive """ return _REGEX_MATCHES_GLOBAL_ASSET_ID_LITERALLY.match(text) is not None
[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 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.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_non_empty_string(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 error in self.transform(that.refers_to): 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_non_empty_string(that.version): error.path._prepend(PropertySegment(that, "version")) yield error if that.revision is not None: for error in verify_non_empty_string(that.revision): error.path._prepend(PropertySegment(that, "revision")) 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 specifies no duplicate 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 specifies no duplicate 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 (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 self.transform(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.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 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_non_empty_string(that.name): error.path._prepend(PropertySegment(that, "name")) yield error for error in verify_non_empty_string(that.value): error.path._prepend(PropertySegment(that, "value")) yield error 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 specifies no duplicate 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 specifies no duplicate 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(element.id_short is not None for element in that.submodel_elements)) ): yield Error("ID-shorts need to be defined for all the submodel elements.") if not ( not (that.submodel_elements is not None) or id_shorts_are_unique(that.submodel_elements) ): yield Error( "Constraint AASd-120: ID-short of non-identifiable " + "referables shall be unique in its namespace." ) if not ( not (that.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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.value is not None) and ( ( 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 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-shorts of submodel elements within " + "a SubmodelElementList 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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.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 # 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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(element.id_short is not None for element in that.value)) ): yield Error("ID-shorts need to be defined for all the elements.") 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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 specifies no duplicate 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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 ( ( ( ( that.entity_type == aas_types.EntityType.SELF_MANAGED_ENTITY and ( ( ( ( (that.global_asset_id is not None) and (that.specific_asset_id is None) ) ) or ( ( (that.global_asset_id is None) and (that.specific_asset_id is not None) ) ) ) ) ) ) or ( ( (that.global_asset_id is None) and (that.specific_asset_id 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 " + "'SelfManagedEntity'. They are not existing otherwise." ) 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 self.transform(that.global_asset_id): error.path._prepend(PropertySegment(that, "global_asset_id")) yield error if that.specific_asset_id is not None: for error in self.transform(that.specific_asset_id): error.path._prepend(PropertySegment(that, "specific_asset_id")) yield error # noinspection PyMethodMayBeStatic def transform_event_payload(self, that: aas_types.EventPayload) -> Iterator[Error]: if not is_model_reference_to_referable(that.source): yield Error("Source must be a model reference to a referable.") 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_non_empty_string(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_stamp_utc(that.time_stamp): error.path._prepend(PropertySegment(that, "time_stamp")) yield error if that.payload is not None: for error in verify_non_empty_string(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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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_non_empty_string(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_stamp_utc(that.last_update): error.path._prepend(PropertySegment(that, "last_update")) yield error if that.min_interval is not None: for error in verify_date_time_stamp_utc(that.min_interval): error.path._prepend(PropertySegment(that, "min_interval")) yield error if that.max_interval is not None: for error in verify_date_time_stamp_utc(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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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 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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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]: 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 specifies no duplicate 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 specifies no duplicate 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.qualifiers is not None) or ( not ( any( qualifier.kind == aas_types.QualifierKind.TEMPLATE_QUALIFIER for qualifier in that.qualifiers ) ) or (that.kind_or_default() == aas_types.ModelingKind.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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 specifies no duplicate 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 specifies no duplicate 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.category is not None) or (that.category in aas_constants.VALID_CATEGORIES_FOR_CONCEPT_DESCRIPTION) ): yield Error( "Constraint AASd-051: A concept description shall have one " + "of the following categories: 'VALUE', 'PROPERTY', " + "'REFERENCE', 'DOCUMENT', 'CAPABILITY',; 'RELATIONSHIP', " + "'COLLECTION', 'FUNCTION', 'EVENT', 'ENTITY', " + "'APPLICATION_CLASS', 'QUALIFIER', 'VIEW'." ) if not ( not ( ( (that.category is not None) and that.category != "VALUE" and (that.embedded_data_specifications is not None) ) ) or data_specification_iec_61360s_have_definition_at_least_in_english( that.embedded_data_specifications ) ): yield Error( "Constraint AASc-003: For all concept descriptions with " + "a category except VALUE using data specification IEC 61360, " + "the definition of the data specification is mandatory and " + "shall be defined at least in English." ) if not ( not ( ( (that.category is not None) and that.category == "VALUE" and (that.embedded_data_specifications is not None) ) ) or data_specification_iec_61360s_have_value( that.embedded_data_specifications ) ): yield Error( "Constraint AASc-008: For a concept description with " + "category VALUE using data specification IEC 61360, " + "the value of the data specification shall be set." ) 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-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-006: For a concept description with " + "category DOCUMENT using data specification IEC 61360, " + "the data type of the data specification is mandatory and " + "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-005: For a concept description with " + "category REFERENCE using data specification IEC 61360, " + "the data type of the data specification is mandatory and " + "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-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_non_empty_string(that.category): error.path._prepend(PropertySegment(that, "category")) yield error if that.id_short is not None: for error in verify_id_short(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.checksum is not None: for error in verify_non_empty_string(that.checksum): error.path._prepend(PropertySegment(that, "checksum")) 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 type of the first " + "key shall be one of Globally identifiables." ) if not ( not ( ( that.type == aas_types.ReferenceTypes.GLOBAL_REFERENCE and len(that.keys) >= 1 ) ) or (that.keys[0].type in aas_constants.GENERIC_GLOBALLY_IDENTIFIABLES) ): yield Error( "Constraint AASd-122: For global references the type of " + "the first key 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 type of " + "the first key shall be one of AAS identifiables" ) if not ( not ( ( that.type == aas_types.ReferenceTypes.GLOBAL_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 global references the last key " + "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, the type of the keys following the first key 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, the 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, 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_positive_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_non_empty_string(that.value): error.path._prepend(PropertySegment(that, "value")) yield error # noinspection PyMethodMayBeStatic def transform_lang_string(self, that: aas_types.LangString) -> Iterator[Error]: for error in verify_bcp_47_language_tag(that.language): error.path._prepend(PropertySegment(that, "language")) 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_value_reference_pair( self, that: aas_types.ValueReferencePair ) -> Iterator[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_data_specification_iec_61360( self, that: aas_types.DataSpecificationIEC61360 ) -> Iterator[Error]: if not ( ( (((that.value is not None) and (that.value_list is None))) or ( ( (that.value is None) and (that.value_list is not None) and len(that.value_list.value_reference_pairs) >= 1 ) ) ) ): yield Error( "Constraint AASc-010: If value is not empty then value list " + "shall be empty and vice versa." ) if not ( not ( ( (that.data_type is 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-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 specifies no duplicate 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 specifies no duplicate 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 specifies no duplicate languages") if not ( any( is_bcp_47_for_english(lang_string.language) for lang_string in that.preferred_name ) ): yield Error( "Constraint AASc-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_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_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_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_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 # noinspection PyMethodMayBeStatic def transform_data_specification_physical_unit( self, that: aas_types.DataSpecificationPhysicalUnit ) -> Iterator[Error]: if not (len(that.definition) >= 1): yield Error("Definition must have at least one item") if not (lang_strings_have_unique_languages(that.definition)): yield Error("Definition specifies no duplicate languages") for error in verify_non_empty_string(that.unit_name): error.path._prepend(PropertySegment(that, "unit_name")) yield error for error in verify_non_empty_string(that.unit_symbol): error.path._prepend(PropertySegment(that, "unit_symbol")) yield error for i, an_item in enumerate(that.definition): for error in self.transform(an_item): error.path._prepend(IndexSegment(that.definition, i)) error.path._prepend(PropertySegment(that, "definition")) yield error if that.si_notation is not None: for error in verify_non_empty_string(that.si_notation): error.path._prepend(PropertySegment(that, "si_notation")) yield error if that.si_name is not None: for error in verify_non_empty_string(that.si_name): error.path._prepend(PropertySegment(that, "si_name")) yield error if that.din_notation is not None: for error in verify_non_empty_string(that.din_notation): error.path._prepend(PropertySegment(that, "din_notation")) yield error if that.ece_name is not None: for error in verify_non_empty_string(that.ece_name): error.path._prepend(PropertySegment(that, "ece_name")) yield error if that.ece_code is not None: for error in verify_non_empty_string(that.ece_code): error.path._prepend(PropertySegment(that, "ece_code")) yield error if that.nist_name is not None: for error in verify_non_empty_string(that.nist_name): error.path._prepend(PropertySegment(that, "nist_name")) yield error if that.source_of_definition is not None: for error in verify_non_empty_string(that.source_of_definition): error.path._prepend(PropertySegment(that, "source_of_definition")) yield error if that.conversion_factor is not None: for error in verify_non_empty_string(that.conversion_factor): error.path._prepend(PropertySegment(that, "conversion_factor")) yield error if that.registration_authority_id is not None: for error in verify_non_empty_string(that.registration_authority_id): error.path._prepend(PropertySegment(that, "registration_authority_id")) yield error if that.supplier is not None: for error in verify_non_empty_string(that.supplier): error.path._prepend(PropertySegment(that, "supplier")) 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_non_empty_string(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not (len(that) >= 1): yield Error( "Constraint AASd-100: An attribute with data type ``string`` " + "is not allowed to be empty." )
[docs]def verify_date_time_stamp_utc(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not matches_xs_date_time_stamp_utc(that): yield Error( "The value must match the pattern of xs:dateTimeStamp with " + "the time zone fixed to UTC." ) if not is_xs_date_time_stamp_utc(that): yield Error( "The value must represent a valid xs:dateTimeStamp with " + "the time zone fixed to UTC." )
# 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 (len(that) >= 1): yield Error( "Constraint AASd-100: An attribute with data type ``string`` " + "is not allowed to be empty." )
[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 (len(that) >= 1): yield Error( "Constraint AASd-100: An attribute with data type ``string`` " + "is not allowed to be empty." ) 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 (len(that) >= 1): yield Error( "Constraint AASd-100: An attribute with data type ``string`` " + "is not allowed to be empty." ) if not matches_rfc_8089_path(that): yield Error( "The value must represent a valid file URI scheme according " + "to RFC 8089." )
[docs]def verify_qualifier_type(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not (len(that) >= 1): yield Error( "Constraint AASd-100: An attribute with data type ``string`` " + "is not allowed to be empty." )
# noinspection PyUnusedLocal
[docs]def verify_value_data_type(that: str) -> 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_id_short(that: str) -> Iterator[Error]: """Verify the constraints of :paramref:`that`.""" if not (len(that) <= 128): yield Error( "Constraint AASd-027: ID-short 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.