cognite-neat 0.88.3__py3-none-any.whl → 0.90.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/_version.py +1 -1
- cognite/neat/constants.py +6 -3
- cognite/neat/graph/extractors/__init__.py +2 -0
- cognite/neat/graph/extractors/_classic_cdf/_base.py +2 -2
- cognite/neat/graph/extractors/_dms.py +158 -0
- cognite/neat/graph/extractors/_mock_graph_generator.py +50 -9
- cognite/neat/graph/loaders/_rdf2dms.py +16 -13
- cognite/neat/graph/models.py +1 -0
- cognite/neat/graph/queries/_base.py +4 -2
- cognite/neat/issues/_base.py +3 -1
- cognite/neat/issues/errors/__init__.py +2 -1
- cognite/neat/issues/errors/_general.py +7 -0
- cognite/neat/issues/warnings/__init__.py +2 -0
- cognite/neat/issues/warnings/_models.py +1 -1
- cognite/neat/issues/warnings/_properties.py +12 -0
- cognite/neat/issues/warnings/user_modeling.py +1 -1
- cognite/neat/rules/_shared.py +49 -6
- cognite/neat/rules/analysis/_base.py +1 -1
- cognite/neat/rules/exporters/_base.py +7 -18
- cognite/neat/rules/exporters/_rules2dms.py +8 -18
- cognite/neat/rules/exporters/_rules2excel.py +5 -12
- cognite/neat/rules/exporters/_rules2ontology.py +9 -19
- cognite/neat/rules/exporters/_rules2yaml.py +3 -6
- cognite/neat/rules/importers/_base.py +7 -52
- cognite/neat/rules/importers/_dms2rules.py +172 -116
- cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +26 -18
- cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +14 -30
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2classes.py +7 -3
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2metadata.py +3 -3
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2properties.py +18 -11
- cognite/neat/rules/importers/_rdf/_imf2rules/_imf2rules.py +9 -18
- cognite/neat/rules/importers/_rdf/_inference2rules.py +37 -65
- cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +9 -20
- cognite/neat/rules/importers/_rdf/_shared.py +1 -1
- cognite/neat/rules/importers/_spreadsheet2rules.py +22 -86
- cognite/neat/rules/importers/_yaml2rules.py +14 -41
- cognite/neat/rules/models/__init__.py +21 -5
- cognite/neat/rules/models/_base_input.py +162 -0
- cognite/neat/rules/models/{_base.py → _base_rules.py} +1 -12
- cognite/neat/rules/models/asset/__init__.py +5 -2
- cognite/neat/rules/models/asset/_rules.py +2 -20
- cognite/neat/rules/models/asset/_rules_input.py +40 -115
- cognite/neat/rules/models/asset/_validation.py +1 -1
- cognite/neat/rules/models/data_types.py +150 -44
- cognite/neat/rules/models/dms/__init__.py +19 -7
- cognite/neat/rules/models/dms/_exporter.py +82 -39
- cognite/neat/rules/models/dms/_rules.py +42 -155
- cognite/neat/rules/models/dms/_rules_input.py +186 -254
- cognite/neat/rules/models/dms/_serializer.py +44 -3
- cognite/neat/rules/models/dms/_validation.py +3 -4
- cognite/neat/rules/models/domain.py +52 -1
- cognite/neat/rules/models/entities/__init__.py +63 -0
- cognite/neat/rules/models/entities/_constants.py +73 -0
- cognite/neat/rules/models/entities/_loaders.py +76 -0
- cognite/neat/rules/models/entities/_multi_value.py +67 -0
- cognite/neat/rules/models/{entities.py → entities/_single_value.py} +74 -232
- cognite/neat/rules/models/entities/_types.py +86 -0
- cognite/neat/rules/models/{wrapped_entities.py → entities/_wrapped.py} +1 -1
- cognite/neat/rules/models/information/__init__.py +10 -2
- cognite/neat/rules/models/information/_rules.py +3 -14
- cognite/neat/rules/models/information/_rules_input.py +57 -204
- cognite/neat/rules/models/information/_validation.py +1 -1
- cognite/neat/rules/transformers/__init__.py +21 -0
- cognite/neat/rules/transformers/_base.py +69 -3
- cognite/neat/rules/{models/information/_converter.py → transformers/_converters.py} +226 -21
- cognite/neat/rules/transformers/_map_onto.py +97 -0
- cognite/neat/rules/transformers/_pipelines.py +61 -0
- cognite/neat/rules/transformers/_verification.py +136 -0
- cognite/neat/store/_base.py +2 -2
- cognite/neat/store/_provenance.py +10 -1
- cognite/neat/utils/cdf/data_classes.py +20 -0
- cognite/neat/utils/regex_patterns.py +6 -0
- cognite/neat/workflows/steps/lib/current/rules_exporter.py +106 -37
- cognite/neat/workflows/steps/lib/current/rules_importer.py +24 -22
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/METADATA +1 -1
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/RECORD +80 -74
- cognite/neat/rules/models/_constants.py +0 -2
- cognite/neat/rules/models/_types/__init__.py +0 -19
- cognite/neat/rules/models/asset/_converter.py +0 -4
- cognite/neat/rules/models/dms/_converter.py +0 -143
- /cognite/neat/rules/models/{_types/_field.py → _types.py} +0 -0
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.88.3.dist-info → cognite_neat-0.90.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import math
|
|
2
|
+
from dataclasses import dataclass, field
|
|
2
3
|
from typing import Any, ClassVar
|
|
3
4
|
|
|
4
5
|
from pydantic import Field, field_serializer, field_validator, model_serializer
|
|
@@ -7,7 +8,8 @@ from pydantic_core.core_schema import SerializationInfo
|
|
|
7
8
|
from cognite.neat.rules.models.data_types import DataType
|
|
8
9
|
from cognite.neat.rules.models.entities import ClassEntity, ClassEntityList
|
|
9
10
|
|
|
10
|
-
from .
|
|
11
|
+
from ._base_input import InputComponent, InputRules
|
|
12
|
+
from ._base_rules import (
|
|
11
13
|
BaseMetadata,
|
|
12
14
|
BaseRules,
|
|
13
15
|
RoleTypes,
|
|
@@ -76,3 +78,52 @@ class DomainRules(BaseRules):
|
|
|
76
78
|
cls.model_dump(**kwargs) for cls in self.classes or []
|
|
77
79
|
] or None
|
|
78
80
|
return output
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass
|
|
84
|
+
class DomainInputMetadata(InputComponent[DomainMetadata]):
|
|
85
|
+
creator: str
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def _get_verified_cls(cls) -> type[DomainMetadata]:
|
|
89
|
+
return DomainMetadata
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass
|
|
93
|
+
class DomainInputProperty(InputComponent[DomainProperty]):
|
|
94
|
+
class_: str
|
|
95
|
+
property_: str
|
|
96
|
+
value_type: str
|
|
97
|
+
name: str | None = None
|
|
98
|
+
description: str | None = None
|
|
99
|
+
min_count: int | None = None
|
|
100
|
+
max_count: int | float | None = None
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def _get_verified_cls(cls) -> type[DomainProperty]:
|
|
104
|
+
return DomainProperty
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass
|
|
108
|
+
class DomainInputClass(InputComponent[DomainClass]):
|
|
109
|
+
class_: str
|
|
110
|
+
name: str | None = None
|
|
111
|
+
description: str | None = None
|
|
112
|
+
parent: list[str] | None = None
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def _get_verified_cls(cls) -> type[DomainClass]:
|
|
116
|
+
return DomainClass
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@dataclass
|
|
120
|
+
class DomainInputRules(InputRules[DomainRules]):
|
|
121
|
+
metadata: DomainInputMetadata
|
|
122
|
+
properties: list[DomainInputProperty] = field(default_factory=list)
|
|
123
|
+
classes: list[DomainInputClass] = field(default_factory=list)
|
|
124
|
+
last: "DomainInputRules | None" = None
|
|
125
|
+
reference: "DomainInputRules | None" = None
|
|
126
|
+
|
|
127
|
+
@classmethod
|
|
128
|
+
def _get_verified_cls(cls) -> type[DomainRules]:
|
|
129
|
+
return DomainRules
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from ._constants import EntityTypes, Undefined, Unknown
|
|
2
|
+
from ._loaders import load_connection, load_dms_value_type, load_value_type
|
|
3
|
+
from ._multi_value import MultiValueTypeInfo
|
|
4
|
+
from ._single_value import (
|
|
5
|
+
AssetEntity,
|
|
6
|
+
AssetFields,
|
|
7
|
+
ClassEntity,
|
|
8
|
+
ContainerEntity,
|
|
9
|
+
DataModelEntity,
|
|
10
|
+
DMSEntity,
|
|
11
|
+
DMSNodeEntity,
|
|
12
|
+
DMSUnknownEntity,
|
|
13
|
+
DMSVersionedEntity,
|
|
14
|
+
EdgeEntity,
|
|
15
|
+
Entity,
|
|
16
|
+
ReferenceEntity,
|
|
17
|
+
RelationshipEntity,
|
|
18
|
+
ReverseConnectionEntity,
|
|
19
|
+
T_Entity,
|
|
20
|
+
UnitEntity,
|
|
21
|
+
UnknownEntity,
|
|
22
|
+
ViewEntity,
|
|
23
|
+
)
|
|
24
|
+
from ._types import CdfResourceEntityList, ClassEntityList, ContainerEntityList, URLEntity, ViewEntityList
|
|
25
|
+
from ._wrapped import DMSFilter, HasDataFilter, NodeTypeFilter, RawFilter, WrappedEntity
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"Entity",
|
|
29
|
+
"UnitEntity",
|
|
30
|
+
"DMSVersionedEntity",
|
|
31
|
+
"RelationshipEntity",
|
|
32
|
+
"EdgeEntity",
|
|
33
|
+
"ViewEntity",
|
|
34
|
+
"ClassEntity",
|
|
35
|
+
"ViewEntityList",
|
|
36
|
+
"UnknownEntity",
|
|
37
|
+
"EntityTypes",
|
|
38
|
+
"Unknown",
|
|
39
|
+
"Undefined",
|
|
40
|
+
"T_Entity",
|
|
41
|
+
"AssetEntity",
|
|
42
|
+
"AssetFields",
|
|
43
|
+
"ReverseConnectionEntity",
|
|
44
|
+
"MultiValueTypeInfo",
|
|
45
|
+
"DMSNodeEntity",
|
|
46
|
+
"DMSEntity",
|
|
47
|
+
"ContainerEntity",
|
|
48
|
+
"DMSUnknownEntity",
|
|
49
|
+
"DataModelEntity",
|
|
50
|
+
"ReferenceEntity",
|
|
51
|
+
"ClassEntityList",
|
|
52
|
+
"CdfResourceEntityList",
|
|
53
|
+
"ContainerEntityList",
|
|
54
|
+
"URLEntity",
|
|
55
|
+
"load_value_type",
|
|
56
|
+
"load_dms_value_type",
|
|
57
|
+
"load_connection",
|
|
58
|
+
"WrappedEntity",
|
|
59
|
+
"NodeTypeFilter",
|
|
60
|
+
"DMSFilter",
|
|
61
|
+
"HasDataFilter",
|
|
62
|
+
"RawFilter",
|
|
63
|
+
]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
if sys.version_info >= (3, 11):
|
|
7
|
+
from enum import StrEnum
|
|
8
|
+
else:
|
|
9
|
+
from backports.strenum import StrEnum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EntityTypes(StrEnum):
|
|
13
|
+
view_non_versioned = "view_non_versioned"
|
|
14
|
+
subject = "subject"
|
|
15
|
+
predicate = "predicate"
|
|
16
|
+
object = "object"
|
|
17
|
+
class_ = "class"
|
|
18
|
+
parent_class = "parent_class"
|
|
19
|
+
property_ = "property"
|
|
20
|
+
object_property = "ObjectProperty"
|
|
21
|
+
data_property = "DatatypeProperty"
|
|
22
|
+
annotation_property = "AnnotationProperty"
|
|
23
|
+
object_value_type = "object_value_type"
|
|
24
|
+
data_value_type = "data_value_type" # these are strings, floats, ...
|
|
25
|
+
xsd_value_type = "xsd_value_type"
|
|
26
|
+
dms_value_type = "dms_value_type"
|
|
27
|
+
dms_node = "dms_node"
|
|
28
|
+
view = "view"
|
|
29
|
+
reference_entity = "reference_entity"
|
|
30
|
+
container = "container"
|
|
31
|
+
datamodel = "datamodel"
|
|
32
|
+
undefined = "undefined"
|
|
33
|
+
multi_value_type = "multi_value_type"
|
|
34
|
+
asset = "asset"
|
|
35
|
+
relationship = "relationship"
|
|
36
|
+
edge = "edge"
|
|
37
|
+
reverse = "reverse"
|
|
38
|
+
unit = "unit"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# ALLOWED
|
|
42
|
+
_ALLOWED_PATTERN = r"[^a-zA-Z0-9-_.]"
|
|
43
|
+
|
|
44
|
+
# FOR PARSING STRINGS:
|
|
45
|
+
_PREFIX_REGEX = r"[a-zA-Z]+[a-zA-Z0-9-_.]*[a-zA-Z0-9]+"
|
|
46
|
+
_SUFFIX_REGEX = r"[a-zA-Z0-9-_.]+[a-zA-Z0-9]|[-_.]*[a-zA-Z0-9]+"
|
|
47
|
+
_VERSION_REGEX = r"[a-zA-Z0-9]([.a-zA-Z0-9_-]{0,41}[a-zA-Z0-9])?"
|
|
48
|
+
_PROPERTY_REGEX = r"[a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9]?"
|
|
49
|
+
_ENTITY_ID_REGEX = rf"{_PREFIX_REGEX}:({_SUFFIX_REGEX})"
|
|
50
|
+
_ENTITY_ID_REGEX_COMPILED = re.compile(rf"^(?P<prefix>{_PREFIX_REGEX}):(?P<suffix>{_SUFFIX_REGEX})$")
|
|
51
|
+
_VERSIONED_ENTITY_REGEX_COMPILED = re.compile(
|
|
52
|
+
rf"^(?P<prefix>{_PREFIX_REGEX}):(?P<suffix>{_SUFFIX_REGEX})\(version=(?P<version>{_VERSION_REGEX})\)$"
|
|
53
|
+
)
|
|
54
|
+
_CLASS_ID_REGEX = rf"(?P<{EntityTypes.class_}>{_ENTITY_ID_REGEX})"
|
|
55
|
+
_CLASS_ID_REGEX_COMPILED = re.compile(rf"^{_CLASS_ID_REGEX}$")
|
|
56
|
+
_PROPERTY_ID_REGEX = rf"\((?P<{EntityTypes.property_}>{_ENTITY_ID_REGEX})\)"
|
|
57
|
+
|
|
58
|
+
ENTITY_PATTERN = re.compile(r"^(?P<prefix>.*?):?(?P<suffix>[^(:]*)(\((?P<content>.+)\))?$")
|
|
59
|
+
MULTI_VALUE_TYPE_PATTERN = re.compile(r"^(?P<types>.*?)(\((?P<content>[^)]+)\))?$")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class _UndefinedType(BaseModel): ...
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class _UnknownType(BaseModel):
|
|
66
|
+
def __str__(self) -> str:
|
|
67
|
+
return "#N/A"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# This is a trick to make Undefined and Unknown singletons
|
|
71
|
+
Undefined = _UndefinedType()
|
|
72
|
+
Unknown = _UnknownType()
|
|
73
|
+
_PARSE = object()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from cognite.neat.issues.errors import NeatTypeError
|
|
4
|
+
from cognite.neat.rules.models.data_types import DataType
|
|
5
|
+
|
|
6
|
+
from ._multi_value import MultiValueTypeInfo
|
|
7
|
+
from ._single_value import (
|
|
8
|
+
ClassEntity,
|
|
9
|
+
DMSUnknownEntity,
|
|
10
|
+
EdgeEntity,
|
|
11
|
+
ReverseConnectionEntity,
|
|
12
|
+
Unknown,
|
|
13
|
+
UnknownEntity,
|
|
14
|
+
ViewEntity,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def load_value_type(
|
|
19
|
+
raw: str | MultiValueTypeInfo | DataType | ClassEntity | UnknownEntity, default_prefix: str
|
|
20
|
+
) -> MultiValueTypeInfo | DataType | ClassEntity | UnknownEntity:
|
|
21
|
+
if isinstance(raw, MultiValueTypeInfo | DataType | ClassEntity | UnknownEntity):
|
|
22
|
+
return raw
|
|
23
|
+
elif isinstance(raw, str):
|
|
24
|
+
# property holding xsd data type
|
|
25
|
+
# check if it is multi value type
|
|
26
|
+
if "|" in raw:
|
|
27
|
+
value_type = MultiValueTypeInfo.load(raw)
|
|
28
|
+
value_type.set_default_prefix(default_prefix)
|
|
29
|
+
return value_type
|
|
30
|
+
elif DataType.is_data_type(raw):
|
|
31
|
+
return DataType.load(raw)
|
|
32
|
+
|
|
33
|
+
# unknown value type
|
|
34
|
+
elif raw == str(Unknown):
|
|
35
|
+
return UnknownEntity()
|
|
36
|
+
|
|
37
|
+
# property holding link to class
|
|
38
|
+
else:
|
|
39
|
+
return ClassEntity.load(raw, prefix=default_prefix)
|
|
40
|
+
else:
|
|
41
|
+
raise NeatTypeError(f"Invalid value type: {type(raw)}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def load_dms_value_type(
|
|
45
|
+
raw: str | DataType | ViewEntity | DMSUnknownEntity,
|
|
46
|
+
default_space: str,
|
|
47
|
+
default_version: str,
|
|
48
|
+
) -> DataType | ViewEntity | DMSUnknownEntity:
|
|
49
|
+
if isinstance(raw, DataType | ViewEntity | DMSUnknownEntity):
|
|
50
|
+
return raw
|
|
51
|
+
elif isinstance(raw, str):
|
|
52
|
+
if DataType.is_data_type(raw):
|
|
53
|
+
return DataType.load(raw)
|
|
54
|
+
elif raw == str(Unknown):
|
|
55
|
+
return DMSUnknownEntity()
|
|
56
|
+
else:
|
|
57
|
+
return ViewEntity.load(raw, space=default_space, version=default_version)
|
|
58
|
+
raise NeatTypeError(f"Invalid value type: {type(raw)}")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def load_connection(
|
|
62
|
+
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
63
|
+
default_space: str,
|
|
64
|
+
default_version: str,
|
|
65
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None:
|
|
66
|
+
if (
|
|
67
|
+
isinstance(raw, EdgeEntity | ReverseConnectionEntity)
|
|
68
|
+
or raw is None
|
|
69
|
+
or (isinstance(raw, str) and raw == "direct")
|
|
70
|
+
):
|
|
71
|
+
return raw # type: ignore[return-value]
|
|
72
|
+
elif isinstance(raw, str) and raw.startswith("edge"):
|
|
73
|
+
return EdgeEntity.load(raw, space=default_space, version=default_version) # type: ignore[return-value]
|
|
74
|
+
elif isinstance(raw, str) and raw.startswith("reverse"):
|
|
75
|
+
return ReverseConnectionEntity.load(raw) # type: ignore[return-value]
|
|
76
|
+
raise NeatTypeError(f"Invalid connection: {type(raw)}")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from typing import Any, ClassVar
|
|
2
|
+
|
|
3
|
+
from pydantic import (
|
|
4
|
+
BaseModel,
|
|
5
|
+
model_serializer,
|
|
6
|
+
model_validator,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from cognite.neat.rules.models.data_types import DataType
|
|
10
|
+
|
|
11
|
+
from ._constants import _PARSE, EntityTypes, Undefined
|
|
12
|
+
from ._single_value import ClassEntity, UnknownEntity
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MultiValueTypeInfo(BaseModel):
|
|
16
|
+
type_: ClassVar[EntityTypes] = EntityTypes.multi_value_type
|
|
17
|
+
types: list[DataType | ClassEntity]
|
|
18
|
+
|
|
19
|
+
def __str__(self) -> str:
|
|
20
|
+
return " | ".join([str(t) for t in self.types])
|
|
21
|
+
|
|
22
|
+
@model_serializer(when_used="unless-none", return_type=str)
|
|
23
|
+
def as_str(self) -> str:
|
|
24
|
+
return str(self)
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def load(cls, data: Any) -> "MultiValueTypeInfo":
|
|
28
|
+
# already instance of MultiValueTypeInfo
|
|
29
|
+
if isinstance(data, cls):
|
|
30
|
+
return data
|
|
31
|
+
|
|
32
|
+
# it is a raw string that needs to be parsed
|
|
33
|
+
elif isinstance(data, str):
|
|
34
|
+
return cls.model_validate({_PARSE: data})
|
|
35
|
+
|
|
36
|
+
# it is dict that needs to be parsed
|
|
37
|
+
else:
|
|
38
|
+
return cls.model_validate(data)
|
|
39
|
+
|
|
40
|
+
@model_validator(mode="before")
|
|
41
|
+
def _load(cls, data: Any) -> "dict | MultiValueTypeInfo":
|
|
42
|
+
if isinstance(data, dict) and _PARSE in data:
|
|
43
|
+
data = data[_PARSE]
|
|
44
|
+
elif isinstance(data, dict):
|
|
45
|
+
return data
|
|
46
|
+
else:
|
|
47
|
+
raise ValueError(f"Cannot load {cls.__name__} from {data}")
|
|
48
|
+
|
|
49
|
+
result = cls._parse(data)
|
|
50
|
+
return result
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def _parse(cls, raw: str) -> dict:
|
|
54
|
+
if not (types := [type_.strip() for type_ in raw.split("|")]):
|
|
55
|
+
return {"types": [UnknownEntity()]}
|
|
56
|
+
else:
|
|
57
|
+
return {
|
|
58
|
+
"types": [
|
|
59
|
+
(DataType.load(type_) if DataType.is_data_type(type_) else ClassEntity.load(type_))
|
|
60
|
+
for type_ in types
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
def set_default_prefix(self, prefix: str):
|
|
65
|
+
for type_ in self.types:
|
|
66
|
+
if isinstance(type_, ClassEntity) and type_.prefix is Undefined:
|
|
67
|
+
type_.prefix = prefix
|