diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 00000000..0005a6f7 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,39 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + poetry: + name: Poetry Lockfile Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install poetry + run: pipx install poetry + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: poetry + - name: Check pyproject.toml and poetry.lock + run: poetry check + + lint: + name: Lint Code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + - name: Install tox + run: python -m pip install tox + - name: Run code quality checks + run: tox -e lint \ No newline at end of file diff --git a/linkml_runtime/__init__.py b/linkml_runtime/__init__.py index 3062326e..c5ddc18f 100644 --- a/linkml_runtime/__init__.py +++ b/linkml_runtime/__init__.py @@ -1,7 +1,9 @@ from pathlib import Path + +from rdflib import OWL, RDF, RDFS, SKOS, XSD + from linkml_runtime.utils.curienamespace import CurieNamespace from linkml_runtime.utils.schemaview import SchemaView -from rdflib import RDF, RDFS, SKOS, XSD, OWL __all__ = [ "SchemaView", @@ -12,13 +14,13 @@ # the version in the code import importlib.metadata as importlib_metadata -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -TCCM = CurieNamespace('tccm', 'https://ontologies.r.us/tccm/') -OWL = CurieNamespace('owl', OWL) -RDF = CurieNamespace('rdf', RDF) -RDFS = CurieNamespace('rdfs', RDFS) -SKOS = CurieNamespace('skos', SKOS) -XSD = CurieNamespace('xsd', XSD) +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +TCCM = CurieNamespace("tccm", "https://ontologies.r.us/tccm/") +OWL = CurieNamespace("owl", OWL) +RDF = CurieNamespace("rdf", RDF) +RDFS = CurieNamespace("rdfs", RDFS) +SKOS = CurieNamespace("skos", SKOS) +XSD = CurieNamespace("xsd", XSD) __version__ = importlib_metadata.version(__name__) @@ -39,24 +41,28 @@ URI_TO_LOCAL = { - 'https://w3id.org/linkml/annotations.yaml': str(LINKML_ANNOTATIONS), - 'https://w3id.org/linkml/array.yaml': str(LINKML_ARRAY), - 'https://w3id.org/linkml/extensions.yaml': str(LINKML_EXTENSIONS), - 'https://w3id.org/linkml/mappings.yaml': str(LINKML_MAPPINGS), - 'https://w3id.org/linkml/meta.yaml': str(MAIN_SCHEMA_PATH), - 'https://w3id.org/linkml/types.yaml': str(LINKML_TYPES), - 'https://w3id.org/linkml/units.yaml': str(LINKML_UNITS), - 'https://w3id.org/linkml/validation.yaml': str(LINKML_VALIDATION), + "https://w3id.org/linkml/annotations.yaml": str(LINKML_ANNOTATIONS), + "https://w3id.org/linkml/array.yaml": str(LINKML_ARRAY), + "https://w3id.org/linkml/extensions.yaml": str(LINKML_EXTENSIONS), + "https://w3id.org/linkml/mappings.yaml": str(LINKML_MAPPINGS), + "https://w3id.org/linkml/meta.yaml": str(MAIN_SCHEMA_PATH), + "https://w3id.org/linkml/types.yaml": str(LINKML_TYPES), + "https://w3id.org/linkml/units.yaml": str(LINKML_UNITS), + "https://w3id.org/linkml/validation.yaml": str(LINKML_VALIDATION), } + class MappingError(ValueError): """ An error when mapping elements of a LinkML model to runtime objects """ + pass + class DataNotFoundError(ValueError): """ An error in which data cannot be found """ + pass diff --git a/linkml_runtime/dumpers/__init__.py b/linkml_runtime/dumpers/__init__.py index 6a8f2fee..d69c78f5 100644 --- a/linkml_runtime/dumpers/__init__.py +++ b/linkml_runtime/dumpers/__init__.py @@ -1,9 +1,9 @@ +from linkml_runtime.dumpers.csv_dumper import CSVDumper from linkml_runtime.dumpers.json_dumper import JSONDumper from linkml_runtime.dumpers.rdf_dumper import RDFDumper from linkml_runtime.dumpers.rdflib_dumper import RDFLibDumper from linkml_runtime.dumpers.tsv_dumper import TSVDumper from linkml_runtime.dumpers.yaml_dumper import YAMLDumper -from linkml_runtime.dumpers.csv_dumper import CSVDumper json_dumper = JSONDumper() rdf_dumper = RDFDumper() diff --git a/linkml_runtime/dumpers/delimited_file_dumper.py b/linkml_runtime/dumpers/delimited_file_dumper.py index e5765bb9..c2ec934f 100644 --- a/linkml_runtime/dumpers/delimited_file_dumper.py +++ b/linkml_runtime/dumpers/delimited_file_dumper.py @@ -2,17 +2,16 @@ import json from abc import ABC, abstractmethod from typing import Union + +from json_flattener import GlobalConfig, flatten_to_csv from pydantic import BaseModel -from json_flattener import GlobalConfig from linkml_runtime.dumpers.dumper_root import Dumper from linkml_runtime.dumpers.json_dumper import JSONDumper -from linkml_runtime.utils.yamlutils import YAMLRoot -from linkml_runtime.linkml_model.meta import SlotDefinitionName, SchemaDefinition -from linkml_runtime.utils.schemaview import SchemaView - +from linkml_runtime.linkml_model.meta import SchemaDefinition, SlotDefinitionName from linkml_runtime.utils.csvutils import get_configmap -from json_flattener import flatten_to_csv +from linkml_runtime.utils.schemaview import SchemaView +from linkml_runtime.utils.yamlutils import YAMLRoot class DelimitedFileDumper(Dumper, ABC): @@ -22,12 +21,15 @@ class DelimitedFileDumper(Dumper, ABC): def delimiter(self): pass - def dumps(self, element: Union[BaseModel, YAMLRoot], - index_slot: SlotDefinitionName = None, - schema: SchemaDefinition = None, - schemaview: SchemaView = None, - **kwargs) -> str: - """ Return element formatted as CSV lines """ + def dumps( + self, + element: Union[BaseModel, YAMLRoot], + index_slot: SlotDefinitionName = None, + schema: SchemaDefinition = None, + schemaview: SchemaView = None, + **kwargs, + ) -> str: + """Return element formatted as CSV lines""" json_dumper = JSONDumper() element_j = json.loads(json_dumper.dumps(element)) objs = element_j[index_slot] diff --git a/linkml_runtime/dumpers/dumper_root.py b/linkml_runtime/dumpers/dumper_root.py index 0b111bd1..c1ffd944 100644 --- a/linkml_runtime/dumpers/dumper_root.py +++ b/linkml_runtime/dumpers/dumper_root.py @@ -1,12 +1,13 @@ from abc import ABC, abstractmethod from typing import Union -from linkml_runtime.utils.yamlutils import YAMLRoot from pydantic import BaseModel +from linkml_runtime.utils.yamlutils import YAMLRoot + class Dumper(ABC): - """ Abstract base class for all dumpers """ + """Abstract base class for all dumpers""" def dump(self, element: Union[BaseModel, YAMLRoot], to_file: str, **_) -> None: """ @@ -15,7 +16,7 @@ def dump(self, element: Union[BaseModel, YAMLRoot], to_file: str, **_) -> None: :param to_file: file to dump to :@param _: method specific arguments """ - with open(to_file, 'w', encoding='UTF-8') as output_file: + with open(to_file, "w", encoding="UTF-8") as output_file: output_file.write(self.dumps(element, **_)) @abstractmethod diff --git a/linkml_runtime/dumpers/json_dumper.py b/linkml_runtime/dumpers/json_dumper.py index be5ebc15..23c729ce 100644 --- a/linkml_runtime/dumpers/json_dumper.py +++ b/linkml_runtime/dumpers/json_dumper.py @@ -1,23 +1,24 @@ import json -from datetime import datetime, date +from datetime import date, datetime from decimal import Decimal from typing import Union -from pydantic import BaseModel from deprecated.classic import deprecated +from jsonasobj2 import JsonObj +from pydantic import BaseModel from linkml_runtime.dumpers.dumper_root import Dumper from linkml_runtime.utils import formatutils from linkml_runtime.utils.context_utils import CONTEXTS_PARAM_TYPE from linkml_runtime.utils.formatutils import remove_empty_items from linkml_runtime.utils.yamlutils import YAMLRoot, as_json_object -from jsonasobj2 import JsonObj class JSONDumper(Dumper): - def dump(self, element: Union[BaseModel, YAMLRoot], to_file: str, contexts: CONTEXTS_PARAM_TYPE = None, - **kwargs) -> None: + def dump( + self, element: Union[BaseModel, YAMLRoot], to_file: str, contexts: CONTEXTS_PARAM_TYPE = None, **kwargs + ) -> None: """ Write element as json to to_file :param element: LinkML object to be serialized as YAML @@ -61,12 +62,12 @@ def default(o): return str(o) else: return json.JSONDecoder().decode(o) + if isinstance(element, BaseModel): element = element.model_dump() - return json.dumps(as_json_object(element, contexts, inject_type=inject_type), - default=default, - ensure_ascii=False, - indent=' ') + return json.dumps( + as_json_object(element, contexts, inject_type=inject_type), default=default, ensure_ascii=False, indent=" " + ) @staticmethod @deprecated("Use `utils/formatutils/remove_empty_items` instead") @@ -78,8 +79,9 @@ def remove_empty_items(obj: dict) -> dict: """ return formatutils.remove_empty_items(obj, hide_protected_keys=True) - def to_json_object(self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TYPE = None, - inject_type=True) -> JsonObj: + def to_json_object( + self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TYPE = None, inject_type=True + ) -> JsonObj: """ As dumps(), except returns a JsonObj, not a string diff --git a/linkml_runtime/dumpers/rdf_dumper.py b/linkml_runtime/dumpers/rdf_dumper.py index d49cd496..08110be1 100644 --- a/linkml_runtime/dumpers/rdf_dumper.py +++ b/linkml_runtime/dumpers/rdf_dumper.py @@ -1,19 +1,20 @@ import json from typing import Optional, Union -from pydantic import BaseModel from hbreader import hbread +from pydantic import BaseModel from rdflib import Graph - from linkml_runtime.dumpers.dumper_root import Dumper -from linkml_runtime.utils.context_utils import CONTEXTS_PARAM_TYPE, CONTEXT_TYPE +from linkml_runtime.utils.context_utils import CONTEXT_TYPE, CONTEXTS_PARAM_TYPE from linkml_runtime.utils.formatutils import remove_empty_items from linkml_runtime.utils.yamlutils import YAMLRoot class RDFDumper(Dumper): - def as_rdf_graph(self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TYPE, namespaces: CONTEXT_TYPE = None) -> Graph: + def as_rdf_graph( + self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TYPE, namespaces: CONTEXT_TYPE = None + ) -> Graph: """ Convert element into an RDF graph guided by the context(s) in contexts :param element: element to represent in RDF @@ -29,17 +30,18 @@ def as_rdf_graph(self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_P :return: rdflib Graph containing element """ if contexts is None: - raise Exception(f'Must pass in JSON-LD context via contexts parameter') + raise Exception("Must pass in JSON-LD context via contexts parameter") if isinstance(contexts, list): inp_contexts = [json.loads(hbread(c)) for c in contexts] else: inp_contexts = json.loads(hbread(contexts)) from linkml_runtime.dumpers import json_dumper + jsonld_str = json_dumper.dumps(element) - g = Graph().parse(data=jsonld_str, format='json-ld') - #rdf_jsonld = expand() - #g = rdflib_graph_from_pyld_jsonld(rdf_jsonld) + g = Graph().parse(data=jsonld_str, format="json-ld") + # rdf_jsonld = expand() + # g = rdflib_graph_from_pyld_jsonld(rdf_jsonld) if namespaces is not None: ns_source = json.loads(hbread(namespaces)) @@ -47,24 +49,30 @@ def as_rdf_graph(self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_P ns_source = inp_contexts # TODO: make a utility out of this or add it to prefixcommons - if ns_source and '@context' in ns_source: - ns_contexts = ns_source['@context'] + if ns_source and "@context" in ns_source: + ns_contexts = ns_source["@context"] if isinstance(ns_contexts, dict): ns_contexts = [ns_contexts] for ns_context in ns_contexts: if isinstance(ns_context, dict): for pfx, ns in ns_context.items(): if isinstance(ns, dict): - if '@id' in ns and ns.get('@prefix', False): - ns = ns['@id'] + if "@id" in ns and ns.get("@prefix", False): + ns = ns["@id"] else: continue - if not pfx.startswith('@'): + if not pfx.startswith("@"): g.bind(pfx, ns) return g - def dump(self, element: Union[BaseModel, YAMLRoot], to_file: str, contexts: CONTEXTS_PARAM_TYPE = None, fmt: str = 'turtle') -> None: + def dump( + self, + element: Union[BaseModel, YAMLRoot], + to_file: str, + contexts: CONTEXTS_PARAM_TYPE = None, + fmt: str = "turtle", + ) -> None: """ Write element as rdf to to_file :param element: LinkML object to be emitted @@ -82,7 +90,9 @@ def dump(self, element: Union[BaseModel, YAMLRoot], to_file: str, contexts: CONT element = element.model_dump() super().dump(element, to_file, contexts=contexts, fmt=fmt) - def dumps(self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TYPE = None, fmt: Optional[str] = 'turtle') -> str: + def dumps( + self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TYPE = None, fmt: Optional[str] = "turtle" + ) -> str: """ Convert element into an RDF graph guided by the context(s) in contexts :param element: element to represent in RDF @@ -92,5 +102,4 @@ def dumps(self, element: Union[BaseModel, YAMLRoot], contexts: CONTEXTS_PARAM_TY """ if isinstance(element, BaseModel): element = element.model_dump() - return self.as_rdf_graph(remove_empty_items(element, hide_protected_keys=True), contexts).\ - serialize(format=fmt) + return self.as_rdf_graph(remove_empty_items(element, hide_protected_keys=True), contexts).serialize(format=fmt) diff --git a/linkml_runtime/dumpers/rdflib_dumper.py b/linkml_runtime/dumpers/rdflib_dumper.py index ac8e3df0..1f0ce932 100644 --- a/linkml_runtime/dumpers/rdflib_dumper.py +++ b/linkml_runtime/dumpers/rdflib_dumper.py @@ -1,17 +1,16 @@ import logging import urllib -from typing import Optional, Any, Union -from pydantic import BaseModel +from typing import Any, Optional, Union from curies import Converter -from rdflib import Graph, URIRef, XSD -from rdflib.term import Node, BNode, Literal +from pydantic import BaseModel +from rdflib import XSD, Graph, URIRef from rdflib.namespace import RDF - +from rdflib.term import BNode, Literal, Node from linkml_runtime.dumpers.dumper_root import Dumper -from linkml_runtime.linkml_model import SlotDefinition -from linkml_runtime.utils.schemaview import SchemaView, ElementName, PermissibleValue, PermissibleValueText +from linkml_runtime.linkml_model import ElementName, PermissibleValue, PermissibleValueText, SlotDefinition +from linkml_runtime.utils.schemaview import SchemaView from linkml_runtime.utils.yamlutils import YAMLRoot logger = logging.getLogger(__name__) @@ -26,6 +25,7 @@ class RDFLibDumper(Dumper): This requires a SchemaView object """ + def as_rdf_graph( self, element: Union[BaseModel, YAMLRoot], @@ -45,7 +45,7 @@ def as_rdf_graph( if isinstance(prefix_map, Converter): # TODO replace with `prefix_map = prefix_map.bimap` after making minimum requirement on python 3.8 prefix_map = {record.prefix: record.uri_prefix for record in prefix_map.records} - logger.debug(f'PREFIXMAP={prefix_map}') + logger.debug(f"PREFIXMAP={prefix_map}") namespaces = schemaview.namespaces() if prefix_map: for k, v in prefix_map.items(): @@ -69,7 +69,9 @@ def as_rdf_graph( self.inject_triples(element, schemaview, g) return g - def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, target_type: ElementName = None) -> Node: + def inject_triples( + self, element: Any, schemaview: SchemaView, graph: Graph, target_type: ElementName = None + ) -> Node: """ Inject triples from conversion of element into a Graph @@ -81,7 +83,7 @@ def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, tar """ namespaces = schemaview.namespaces() slot_name_map = schemaview.slot_name_mappings() - logger.debug(f'CONVERT: {element} // {type(element)} // {target_type}') + logger.debug(f"CONVERT: {element} // {type(element)} // {target_type}") if target_type in schemaview.all_enums(): if isinstance(element, PermissibleValueText): e = schemaview.get_enum(target_type) @@ -97,22 +99,22 @@ def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, tar t = schemaview.get_type(target_type) dt_uri = t.uri if dt_uri: - if dt_uri == 'rdfs:Resource': + if dt_uri == "rdfs:Resource": return URIRef(schemaview.expand_curie(element)) - elif dt_uri == 'xsd:string': + elif dt_uri == "xsd:string": return Literal(element) else: if "xsd" not in namespaces: namespaces["xsd"] = XSD return Literal(element, datatype=namespaces.uri_for(dt_uri)) else: - logger.warning(f'No datatype specified for : {t.name}, using plain Literal') + logger.warning(f"No datatype specified for : {t.name}, using plain Literal") return Literal(element) - element_vars = {k: v for k, v in vars(element).items() if not k.startswith('_')} + element_vars = {k: v for k, v in vars(element).items() if not k.startswith("_")} if len(element_vars) == 0: id_slot = schemaview.get_identifier_slot(target_type) return self._as_uri(element, id_slot, schemaview) - #return URIRef(schemaview.expand_curie(str(element))) + # return URIRef(schemaview.expand_curie(str(element))) element_type = type(element) cn = element_type.class_name id_slot = schemaview.get_identifier_slot(cn) @@ -135,7 +137,7 @@ def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, tar if k in slot_name_map: k = slot_name_map[k].name else: - logger.error(f'Slot {k} not in name map') + logger.error(f"Slot {k} not in name map") slot = schemaview.induced_slot(k, cn) if not slot.identifier: slot_uri = URIRef(schemaview.get_uri(slot, expand=True)) @@ -152,7 +154,7 @@ def dump( element: Union[BaseModel, YAMLRoot], to_file: str, schemaview: SchemaView = None, - fmt: str = 'turtle', + fmt: str = "turtle", prefix_map: Union[dict[str, str], Converter, None] = None, **args, ) -> None: @@ -172,7 +174,7 @@ def dumps( self, element: Union[BaseModel, YAMLRoot], schemaview: SchemaView = None, - fmt: Optional[str] = 'turtle', + fmt: Optional[str] = "turtle", prefix_map: Union[dict[str, str], Converter, None] = None, ) -> str: """ @@ -184,12 +186,10 @@ def dumps( :param prefix_map: :return: serialization of rdflib Graph containing element """ - return self.as_rdf_graph(element, schemaview, prefix_map=prefix_map).\ - serialize(format=fmt) + return self.as_rdf_graph(element, schemaview, prefix_map=prefix_map).serialize(format=fmt) def _as_uri(self, element_id: str, id_slot: Optional[SlotDefinition], schemaview: SchemaView) -> URIRef: if id_slot and schemaview.is_slot_percent_encoded(id_slot): return URIRef(urllib.parse.quote(element_id)) else: return schemaview.namespaces().uri_for(element_id) - diff --git a/linkml_runtime/dumpers/yaml_dumper.py b/linkml_runtime/dumpers/yaml_dumper.py index a6360608..39cc10c4 100644 --- a/linkml_runtime/dumpers/yaml_dumper.py +++ b/linkml_runtime/dumpers/yaml_dumper.py @@ -1,20 +1,25 @@ -import yaml from typing import Union + +import yaml from pydantic import BaseModel from linkml_runtime.dumpers.dumper_root import Dumper from linkml_runtime.utils.formatutils import remove_empty_items from linkml_runtime.utils.yamlutils import YAMLRoot + class YAMLDumper(Dumper): def dumps(self, element: Union[BaseModel, YAMLRoot], **kwargs) -> str: - """ Return element formatted as a YAML string """ + """Return element formatted as a YAML string""" # Internal note: remove_empty_items will also convert Decimals to int/float; # this is necessary until https://github.com/yaml/pyyaml/pull/372 is merged dumper_safe_element = element.model_dump() if isinstance(element, BaseModel) else element - return yaml.dump(remove_empty_items(dumper_safe_element, hide_protected_keys=True), - Dumper=yaml.SafeDumper, sort_keys=False, - allow_unicode=True, - **kwargs) + return yaml.dump( + remove_empty_items(dumper_safe_element, hide_protected_keys=True), + Dumper=yaml.SafeDumper, + sort_keys=False, + allow_unicode=True, + **kwargs, + ) diff --git a/linkml_runtime/exceptions.py b/linkml_runtime/exceptions.py index 97a7bfbb..3467ecd1 100644 --- a/linkml_runtime/exceptions.py +++ b/linkml_runtime/exceptions.py @@ -1,2 +1,2 @@ class OrderingError(RuntimeError): - """Exception raised when there is a problem with SchemaView ordering""" \ No newline at end of file + """Exception raised when there is a problem with SchemaView ordering""" diff --git a/linkml_runtime/index/object_index.py b/linkml_runtime/index/object_index.py index a473a1c2..d2a3ec7b 100644 --- a/linkml_runtime/index/object_index.py +++ b/linkml_runtime/index/object_index.py @@ -8,10 +8,11 @@ :ref:`ProxyObject` a proxy for a domain object that "knows" its place in the index """ -import logging + import inspect -from typing import Any, Union -from collections.abc import Mapping, Iterator +import logging +from collections.abc import Iterator, MutableMapping +from typing import Any from linkml_runtime import SchemaView from linkml_runtime.utils import eval_utils @@ -50,13 +51,14 @@ class ObjectIndex: In the above, the same proxy object is reused for any object with an identifier. """ + def __init__(self, obj: YAMLRoot, schemaview: SchemaView): self._root_object = obj self._schemaview = schemaview self._class_map = schemaview.class_name_mappings() - self._source_object_cache: Mapping[str, Any] = {} - self._proxy_object_cache: Mapping[str, ProxyObject] = {} - self._child_to_parent: Mapping[str, list[tuple[str, str]]] = {} + self._source_object_cache: MutableMapping[str, Any] = {} + self._proxy_object_cache: MutableMapping[str, ProxyObject] = {} + self._child_to_parent: MutableMapping[str, list[tuple[str, str]]] = {} self._index(obj) def _index(self, obj: Any, parent_key=None, parent=None): @@ -68,16 +70,11 @@ def _index(self, obj: Any, parent_key=None, parent=None): return {k: self._index(v, parent_key, parent) for k, v in obj.items()} cls_name = type(obj).__name__ if cls_name in self._class_map: - cls = self._class_map[cls_name] pk_val = self._key(obj) self._source_object_cache[pk_val] = obj if pk_val not in self._child_to_parent: self._child_to_parent[pk_val] = [] self._child_to_parent[pk_val].append((parent_key, parent)) - #id_slot = self._schemaview.get_identifier_slot(cls.name) - #if id_slot: - # id_val = getattr(obj, id_slot.name) - # self._source_object_cache[(cls.name, id_val)] = obj for k, v in vars(obj).items(): self._index(v, k, obj) else: @@ -113,7 +110,7 @@ def bless(self, obj: Any) -> "ProxyObject": else: return ProxyObject(obj, _db=self) - def _key(self, obj: Any) -> tuple[Union[str, YAMLRoot], str]: + def _key(self, obj: Any) -> tuple[str, str]: """ Returns primary key value for this object. @@ -162,12 +159,12 @@ def source_object_cache_size(self) -> int: def clear_proxy_object_cache(self): """ Clears all items in the proxy cache. - + :return: """ self._proxy_object_cache = {} - def eval_expr(self, expr: str, obj: Any=None, **kwargs) -> Any: + def eval_expr(self, expr: str, obj: Any = None, **kwargs) -> Any: """ Evaluates an expression against the object store. @@ -212,7 +209,7 @@ def __getattr__(self, p: str) -> Any: return self._map(v, slot.range) def __getattribute__(self, attribute): - if attribute == '__dict__': + if attribute == "__dict__": return {k: getattr(self, k, None) for k in vars(self._shadowed).keys()} else: return object.__getattribute__(self, attribute) @@ -268,4 +265,3 @@ def _map(self, obj: Any, in_range: str) -> Any: def _attributes(self) -> list[str]: return list(vars(self._shadowed).keys()) - diff --git a/linkml_runtime/linkml_model/__init__.py b/linkml_runtime/linkml_model/__init__.py index 587788d0..38ab7d16 100644 --- a/linkml_runtime/linkml_model/__init__.py +++ b/linkml_runtime/linkml_model/__init__.py @@ -1,12 +1,54 @@ -from .types import String, Integer, Boolean, Float, Double, Decimal, Time, Date, Datetime, Uriorcurie, Uri, \ - Ncname, Objectidentifier, Nodeidentifier -from .extensions import Extension, Extensible -from .annotations import Annotation, Annotatable -from .meta import ElementName, SchemaDefinitionName, TypeDefinitionName, SubsetDefinitionName, DefinitionName, \ - EnumDefinitionName, SlotDefinitionName, ClassDefinitionName, PrefixPrefixPrefix, LocalNameLocalNameSource, \ - AltDescriptionSource, PermissibleValueText, Element, SchemaDefinition, TypeDefinition, SubsetDefinition, \ - Definition, EnumDefinition, SlotDefinition, ClassDefinition, Prefix, LocalName, Example, AltDescription, \ - PermissibleValue, PvFormulaOptions +from .annotations import Annotatable, Annotation +from .extensions import Extensible, Extension +from .meta import ( + AltDescription, + AltDescriptionSource, + AnonymousClassExpression, + AnonymousEnumExpression, + AnonymousExpression, + AnonymousSlotExpression, + AnonymousTypeExpression, + ClassDefinition, + ClassDefinitionName, + Definition, + DefinitionName, + Element, + ElementName, + EnumDefinition, + EnumDefinitionName, + Example, + LocalName, + LocalNameLocalNameSource, + PermissibleValue, + PermissibleValueText, + Prefix, + PrefixPrefixPrefix, + PvFormulaOptions, + SchemaDefinition, + SchemaDefinitionName, + SlotDefinition, + SlotDefinitionName, + SubsetDefinition, + SubsetDefinitionName, + TypeDefinition, + TypeDefinitionName, +) +from .types import ( + Boolean, + Date, + Datetime, + Decimal, + Double, + Float, + Integer, + Ncname, + Nodeidentifier, + Objectidentifier, + String, + Time, + Uri, + Uriorcurie, +) __all__ = [ "String", @@ -53,4 +95,9 @@ "AltDescription", "PermissibleValue", "PvFormulaOptions", + "AnonymousClassExpression", + "AnonymousEnumExpression", + "AnonymousExpression", + "AnonymousSlotExpression", + "AnonymousTypeExpression", ] diff --git a/linkml_runtime/linkml_model/annotations.py b/linkml_runtime/linkml_model/annotations.py index 2516c7c3..d430d530 100644 --- a/linkml_runtime/linkml_model/annotations.py +++ b/linkml_runtime/linkml_model/annotations.py @@ -6,26 +6,29 @@ # description: Annotations mixin # license: https://creativecommons.org/publicdomain/zero/1.0/ -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.metamodelcore import empty_dict +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot + from .extensions import AnyValue, Extension, ExtensionTag metamodel_version = "1.7.0" version = "2.0.0" # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") DEFAULT_ = LINKML # Types + # Class references class AnnotationTag(ExtensionTag): pass @@ -36,6 +39,7 @@ class Annotatable(YAMLRoot): """ mixin for classes that support annotations """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Annotatable"] @@ -43,7 +47,9 @@ class Annotatable(YAMLRoot): class_name: ClassVar[str] = "annotatable" class_model_uri: ClassVar[URIRef] = LINKML.Annotatable - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, "Annotation"]], list[Union[dict, "Annotation"]]]] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, "Annotation"]], list[Union[dict, "Annotation"]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self._normalize_inlined_as_dict(slot_name="annotations", slot_type=Annotation, key_name="tag", keyed=True) @@ -56,6 +62,7 @@ class Annotation(Extension): """ a tag/value pair with the semantics of OWL Annotation """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Annotation"] @@ -65,7 +72,9 @@ class Annotation(Extension): tag: Union[str, AnnotationTag] = None value: Union[dict, AnyValue] = None - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, "Annotation"]], list[Union[dict, "Annotation"]]]] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, "Annotation"]], list[Union[dict, "Annotation"]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self._is_empty(self.tag): @@ -85,5 +94,12 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.annotations = Slot(uri=LINKML.annotations, name="annotations", curie=LINKML.curie('annotations'), - model_uri=LINKML.annotations, domain=None, range=Optional[Union[dict[Union[str, AnnotationTag], Union[dict, "Annotation"]], list[Union[dict, "Annotation"]]]]) + +slots.annotations = Slot( + uri=LINKML.annotations, + name="annotations", + curie=LINKML.curie("annotations"), + model_uri=LINKML.annotations, + domain=None, + range=Optional[Union[dict[Union[str, AnnotationTag], Union[dict, "Annotation"]], list[Union[dict, "Annotation"]]]], +) diff --git a/linkml_runtime/linkml_model/datasets.py b/linkml_runtime/linkml_model/datasets.py index 5873b31f..46f8982b 100644 --- a/linkml_runtime/linkml_model/datasets.py +++ b/linkml_runtime/linkml_model/datasets.py @@ -21,31 +21,32 @@ version = None # Namespaces -BIBO = CurieNamespace('bibo', 'http://purl.org/ontology/bibo/') -CSVW = CurieNamespace('csvw', 'http://www.w3.org/ns/csvw#') -DATASETS = CurieNamespace('datasets', 'https://w3id.org/linkml/report') -DCAT = CurieNamespace('dcat', 'http://www.w3.org/ns/dcat#') -DCTERMS = CurieNamespace('dcterms', 'http://purl.org/dc/terms/') -FORMATS = CurieNamespace('formats', 'http://www.w3.org/ns/formats/') -FRICTIONLESS = CurieNamespace('frictionless', 'https://specs.frictionlessdata.io/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -MEDIATYPES = CurieNamespace('mediatypes', 'https://www.iana.org/assignments/media-types/') -OSLC = CurieNamespace('oslc', 'http://open-services.net/ns/core#') -OWL = CurieNamespace('owl', 'http://www.w3.org/2002/07/owl#') -PAV = CurieNamespace('pav', 'http://purl.org/pav/') -PROV = CurieNamespace('prov', 'http://www.w3.org/ns/prov#') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SH = CurieNamespace('sh', 'https://w3id.org/shacl/') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -VOID = CurieNamespace('void', 'http://rdfs.org/ns/void#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +BIBO = CurieNamespace("bibo", "http://purl.org/ontology/bibo/") +CSVW = CurieNamespace("csvw", "http://www.w3.org/ns/csvw#") +DATASETS = CurieNamespace("datasets", "https://w3id.org/linkml/report") +DCAT = CurieNamespace("dcat", "http://www.w3.org/ns/dcat#") +DCTERMS = CurieNamespace("dcterms", "http://purl.org/dc/terms/") +FORMATS = CurieNamespace("formats", "http://www.w3.org/ns/formats/") +FRICTIONLESS = CurieNamespace("frictionless", "https://specs.frictionlessdata.io/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +MEDIATYPES = CurieNamespace("mediatypes", "https://www.iana.org/assignments/media-types/") +OSLC = CurieNamespace("oslc", "http://open-services.net/ns/core#") +OWL = CurieNamespace("owl", "http://www.w3.org/2002/07/owl#") +PAV = CurieNamespace("pav", "http://purl.org/pav/") +PROV = CurieNamespace("prov", "http://www.w3.org/ns/prov#") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SH = CurieNamespace("sh", "https://w3id.org/shacl/") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +VOID = CurieNamespace("void", "http://rdfs.org/ns/void#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = DATASETS # Types + # Class references class InformationId(extended_str): pass @@ -64,6 +65,7 @@ class Information(YAMLRoot): """ Grouping for datasets and data files """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = DATASETS["Information"] @@ -161,6 +163,7 @@ class DataPackage(Information): """ A collection of data resources """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = VOID["Dataset"] @@ -189,6 +192,7 @@ class DataResource(Information): """ An individual file or table """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = DCAT["Distribution"] @@ -256,6 +260,7 @@ class FormatDialect(YAMLRoot): """ Additional format information for a file """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = DATASETS["FormatDialect"] @@ -298,11 +303,10 @@ class TestRole(EnumDefinitionImpl): name="TestRole", ) + class MediaTypeEnum(EnumDefinitionImpl): - csv = PermissibleValue( - text="csv", - meaning=MEDIATYPES["text/csv"]) + csv = PermissibleValue(text="csv", meaning=MEDIATYPES["text/csv"]) _defn = EnumDefinition( name="MediaTypeEnum", @@ -310,31 +314,17 @@ class MediaTypeEnum(EnumDefinitionImpl): @classmethod def _addvals(cls): - setattr(cls, "rdf-xml", - PermissibleValue( - text="rdf-xml", - meaning=MEDIATYPES["application/rdf+xml"])) + setattr(cls, "rdf-xml", PermissibleValue(text="rdf-xml", meaning=MEDIATYPES["application/rdf+xml"])) + class FormatEnum(EnumDefinitionImpl): - N3 = PermissibleValue( - text="N3", - meaning=FORMATS["N3"]) - Microdata = PermissibleValue( - text="Microdata", - meaning=FORMATS["microdata"]) - POWDER = PermissibleValue( - text="POWDER", - meaning=FORMATS["POWDER"]) - RDFa = PermissibleValue( - text="RDFa", - meaning=FORMATS["RDFa"]) - Turtle = PermissibleValue( - text="Turtle", - meaning=FORMATS["Turtle"]) - TriG = PermissibleValue( - text="TriG", - meaning=FORMATS["TriG"]) + N3 = PermissibleValue(text="N3", meaning=FORMATS["N3"]) + Microdata = PermissibleValue(text="Microdata", meaning=FORMATS["microdata"]) + POWDER = PermissibleValue(text="POWDER", meaning=FORMATS["POWDER"]) + RDFa = PermissibleValue(text="RDFa", meaning=FORMATS["RDFa"]) + Turtle = PermissibleValue(text="Turtle", meaning=FORMATS["Turtle"]) + TriG = PermissibleValue(text="TriG", meaning=FORMATS["TriG"]) YAML = PermissibleValue(text="YAML") JSON = PermissibleValue(text="JSON") @@ -344,192 +334,398 @@ class FormatEnum(EnumDefinitionImpl): @classmethod def _addvals(cls): - setattr(cls, "JSON-LD", - PermissibleValue( - text="JSON-LD", - meaning=FORMATS["JSON-LD"])) - setattr(cls, "N-Triples", - PermissibleValue( - text="N-Triples", - meaning=FORMATS["N-Triples"])) - setattr(cls, "N-Quads", - PermissibleValue( - text="N-Quads", - meaning=FORMATS["N-Quads"])) - setattr(cls, "LD Patch", - PermissibleValue( - text="LD Patch", - meaning=FORMATS["LD_Patch"])) - setattr(cls, "OWL XML Serialization", - PermissibleValue( - text="OWL XML Serialization", - meaning=FORMATS["OWL_XML"])) - setattr(cls, "OWL Functional Syntax", - PermissibleValue( - text="OWL Functional Syntax", - meaning=FORMATS["OWL_Functional"])) - setattr(cls, "OWL Manchester Syntax", - PermissibleValue( - text="OWL Manchester Syntax", - meaning=FORMATS["OWL_Manchester"])) - setattr(cls, "POWDER-S", - PermissibleValue( - text="POWDER-S", - meaning=FORMATS["POWDER-S"])) - setattr(cls, "PROV-N", - PermissibleValue( - text="PROV-N", - meaning=FORMATS["PROV-N"])) - setattr(cls, "PROV-XML", - PermissibleValue( - text="PROV-XML", - meaning=FORMATS["PROV-XML"])) - setattr(cls, "RDF/JSON", - PermissibleValue( - text="RDF/JSON", - meaning=FORMATS["RDF_JSON"])) - setattr(cls, "RDF/XML", - PermissibleValue( - text="RDF/XML", - meaning=FORMATS["RDF_XML"])) - setattr(cls, "RIF XML Syntax", - PermissibleValue( - text="RIF XML Syntax", - meaning=FORMATS["RIF_XML"])) - setattr(cls, "SPARQL Results in XML", - PermissibleValue( - text="SPARQL Results in XML", - meaning=FORMATS["SPARQL_Results_XML"])) - setattr(cls, "SPARQL Results in JSON", - PermissibleValue( - text="SPARQL Results in JSON", - meaning=FORMATS["SPARQL_Results_JSON"])) - setattr(cls, "SPARQL Results in CSV", - PermissibleValue( - text="SPARQL Results in CSV", - meaning=FORMATS["SPARQL_Results_CSV"])) - setattr(cls, "SPARQL Results in TSV", - PermissibleValue( - text="SPARQL Results in TSV", - meaning=FORMATS["SPARQL_Results_TSV"])) + setattr(cls, "JSON-LD", PermissibleValue(text="JSON-LD", meaning=FORMATS["JSON-LD"])) + setattr(cls, "N-Triples", PermissibleValue(text="N-Triples", meaning=FORMATS["N-Triples"])) + setattr(cls, "N-Quads", PermissibleValue(text="N-Quads", meaning=FORMATS["N-Quads"])) + setattr(cls, "LD Patch", PermissibleValue(text="LD Patch", meaning=FORMATS["LD_Patch"])) + setattr( + cls, "OWL XML Serialization", PermissibleValue(text="OWL XML Serialization", meaning=FORMATS["OWL_XML"]) + ) + setattr( + cls, + "OWL Functional Syntax", + PermissibleValue(text="OWL Functional Syntax", meaning=FORMATS["OWL_Functional"]), + ) + setattr( + cls, + "OWL Manchester Syntax", + PermissibleValue(text="OWL Manchester Syntax", meaning=FORMATS["OWL_Manchester"]), + ) + setattr(cls, "POWDER-S", PermissibleValue(text="POWDER-S", meaning=FORMATS["POWDER-S"])) + setattr(cls, "PROV-N", PermissibleValue(text="PROV-N", meaning=FORMATS["PROV-N"])) + setattr(cls, "PROV-XML", PermissibleValue(text="PROV-XML", meaning=FORMATS["PROV-XML"])) + setattr(cls, "RDF/JSON", PermissibleValue(text="RDF/JSON", meaning=FORMATS["RDF_JSON"])) + setattr(cls, "RDF/XML", PermissibleValue(text="RDF/XML", meaning=FORMATS["RDF_XML"])) + setattr(cls, "RIF XML Syntax", PermissibleValue(text="RIF XML Syntax", meaning=FORMATS["RIF_XML"])) + setattr( + cls, + "SPARQL Results in XML", + PermissibleValue(text="SPARQL Results in XML", meaning=FORMATS["SPARQL_Results_XML"]), + ) + setattr( + cls, + "SPARQL Results in JSON", + PermissibleValue(text="SPARQL Results in JSON", meaning=FORMATS["SPARQL_Results_JSON"]), + ) + setattr( + cls, + "SPARQL Results in CSV", + PermissibleValue(text="SPARQL Results in CSV", meaning=FORMATS["SPARQL_Results_CSV"]), + ) + setattr( + cls, + "SPARQL Results in TSV", + PermissibleValue(text="SPARQL Results in TSV", meaning=FORMATS["SPARQL_Results_TSV"]), + ) + # Slots class slots: pass -slots.id = Slot(uri=DCTERMS.identifier, name="id", curie=DCTERMS.curie('identifier'), - model_uri=DATASETS.id, domain=None, range=URIRef) - -slots.title = Slot(uri=DCTERMS.title, name="title", curie=DCTERMS.curie('title'), - model_uri=DATASETS.title, domain=None, range=Optional[str]) - -slots.description = Slot(uri=DCTERMS.description, name="description", curie=DCTERMS.curie('description'), - model_uri=DATASETS.description, domain=None, range=Optional[str]) - -slots.language = Slot(uri=DATASETS.language, name="language", curie=DATASETS.curie('language'), - model_uri=DATASETS.language, domain=None, range=Optional[str]) - -slots.publisher = Slot(uri=DCTERMS.publisher, name="publisher", curie=DCTERMS.curie('publisher'), - model_uri=DATASETS.publisher, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.issued = Slot(uri=DCTERMS.issued, name="issued", curie=DCTERMS.curie('issued'), - model_uri=DATASETS.issued, domain=None, range=Optional[Union[str, XSDDateTime]]) - -slots.page = Slot(uri=DCAT.landingPage, name="page", curie=DCAT.curie('landingPage'), - model_uri=DATASETS.page, domain=None, range=Optional[str]) - -slots.dialect = Slot(uri=CSVW.dialect, name="dialect", curie=CSVW.curie('dialect'), - model_uri=DATASETS.dialect, domain=None, range=Optional[str]) - -slots.bytes = Slot(uri=DCAT.byteSize, name="bytes", curie=DCAT.curie('byteSize'), - model_uri=DATASETS.bytes, domain=None, range=Optional[int]) - -slots.path = Slot(uri=DATASETS.path, name="path", curie=DATASETS.curie('path'), - model_uri=DATASETS.path, domain=None, range=Optional[str]) - -slots.download_url = Slot(uri=DCAT.downloadURL, name="download_url", curie=DCAT.curie('downloadURL'), - model_uri=DATASETS.download_url, domain=None, range=Optional[Union[str, URI]]) - -slots.format = Slot(uri=DCTERMS.format, name="format", curie=DCTERMS.curie('format'), - model_uri=DATASETS.format, domain=None, range=Optional[Union[str, "FormatEnum"]]) - -slots.compression = Slot(uri=DATASETS.compression, name="compression", curie=DATASETS.curie('compression'), - model_uri=DATASETS.compression, domain=None, range=Optional[str]) - -slots.encoding = Slot(uri=DATASETS.encoding, name="encoding", curie=DATASETS.curie('encoding'), - model_uri=DATASETS.encoding, domain=None, range=Optional[str]) - -slots.hash = Slot(uri=DATASETS.hash, name="hash", curie=DATASETS.curie('hash'), - model_uri=DATASETS.hash, domain=None, range=Optional[str]) - -slots.sha256 = Slot(uri=DATASETS.sha256, name="sha256", curie=DATASETS.curie('sha256'), - model_uri=DATASETS.sha256, domain=None, range=Optional[str]) - -slots.md5 = Slot(uri=DATASETS.md5, name="md5", curie=DATASETS.curie('md5'), - model_uri=DATASETS.md5, domain=None, range=Optional[str]) - -slots.media_type = Slot(uri=DCAT.mediaType, name="media_type", curie=DCAT.curie('mediaType'), - model_uri=DATASETS.media_type, domain=None, range=Optional[str]) - -slots.conforms_to = Slot(uri=DCTERMS.conformsTo, name="conforms_to", curie=DCTERMS.curie('conformsTo'), - model_uri=DATASETS.conforms_to, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.conforms_to_schema = Slot(uri=DATASETS.conforms_to_schema, name="conforms_to_schema", curie=DATASETS.curie('conforms_to_schema'), - model_uri=DATASETS.conforms_to_schema, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.conforms_to_class = Slot(uri=DATASETS.conforms_to_class, name="conforms_to_class", curie=DATASETS.curie('conforms_to_class'), - model_uri=DATASETS.conforms_to_class, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.profile = Slot(uri=DATASETS.profile, name="profile", curie=DATASETS.curie('profile'), - model_uri=DATASETS.profile, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.keywords = Slot(uri=DCAT.keyword, name="keywords", curie=DCAT.curie('keyword'), - model_uri=DATASETS.keywords, domain=None, range=Optional[Union[str, list[str]]]) - -slots.themes = Slot(uri=DCAT.theme, name="themes", curie=DCAT.curie('theme'), - model_uri=DATASETS.themes, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.resources = Slot(uri=DCAT.distribution, name="resources", curie=DCAT.curie('distribution'), - model_uri=DATASETS.resources, domain=None, range=Optional[Union[Union[str, DataResourceId], list[Union[str, DataResourceId]]]]) - -slots.test_roles = Slot(uri=DATASETS.test_roles, name="test_roles", curie=DATASETS.curie('test_roles'), - model_uri=DATASETS.test_roles, domain=None, range=Optional[Union[Union[str, "TestRole"], list[Union[str, "TestRole"]]]]) - -slots.created_by = Slot(uri=PAV.createdBy, name="created_by", curie=PAV.curie('createdBy'), - model_uri=DATASETS.created_by, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.created_on = Slot(uri=PAV.createdOn, name="created_on", curie=PAV.curie('createdOn'), - model_uri=DATASETS.created_on, domain=None, range=Optional[Union[str, XSDDateTime]]) - -slots.last_updated_on = Slot(uri=PAV.lastUpdatedOn, name="last_updated_on", curie=PAV.curie('lastUpdatedOn'), - model_uri=DATASETS.last_updated_on, domain=None, range=Optional[Union[str, XSDDateTime]]) - -slots.modified_by = Slot(uri=OSLC.modifiedBy, name="modified_by", curie=OSLC.curie('modifiedBy'), - model_uri=DATASETS.modified_by, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.status = Slot(uri=BIBO.status, name="status", curie=BIBO.curie('status'), - model_uri=DATASETS.status, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.license = Slot(uri=DCTERMS.license, name="license", curie=DCTERMS.curie('license'), - model_uri=DATASETS.license, domain=None, range=Optional[str]) - -slots.version = Slot(uri=PAV.version, name="version", curie=PAV.curie('version'), - model_uri=DATASETS.version, domain=None, range=Optional[str]) - -slots.was_derived_from = Slot(uri=PROV.wasDerivedFrom, name="was_derived_from", curie=PROV.curie('wasDerivedFrom'), - model_uri=DATASETS.was_derived_from, domain=None, range=Optional[str]) - -slots.formatDialect__comment_prefix = Slot(uri=DATASETS.comment_prefix, name="formatDialect__comment_prefix", curie=DATASETS.curie('comment_prefix'), - model_uri=DATASETS.formatDialect__comment_prefix, domain=None, range=Optional[str]) - -slots.formatDialect__delimiter = Slot(uri=DATASETS.delimiter, name="formatDialect__delimiter", curie=DATASETS.curie('delimiter'), - model_uri=DATASETS.formatDialect__delimiter, domain=None, range=Optional[str]) - -slots.formatDialect__double_quote = Slot(uri=DATASETS.double_quote, name="formatDialect__double_quote", curie=DATASETS.curie('double_quote'), - model_uri=DATASETS.formatDialect__double_quote, domain=None, range=Optional[str]) - -slots.formatDialect__header = Slot(uri=DATASETS.header, name="formatDialect__header", curie=DATASETS.curie('header'), - model_uri=DATASETS.formatDialect__header, domain=None, range=Optional[str]) -slots.formatDialect__quote_char = Slot(uri=DATASETS.quote_char, name="formatDialect__quote_char", curie=DATASETS.curie('quote_char'), - model_uri=DATASETS.formatDialect__quote_char, domain=None, range=Optional[str]) +slots.id = Slot( + uri=DCTERMS.identifier, + name="id", + curie=DCTERMS.curie("identifier"), + model_uri=DATASETS.id, + domain=None, + range=URIRef, +) + +slots.title = Slot( + uri=DCTERMS.title, + name="title", + curie=DCTERMS.curie("title"), + model_uri=DATASETS.title, + domain=None, + range=Optional[str], +) + +slots.description = Slot( + uri=DCTERMS.description, + name="description", + curie=DCTERMS.curie("description"), + model_uri=DATASETS.description, + domain=None, + range=Optional[str], +) + +slots.language = Slot( + uri=DATASETS.language, + name="language", + curie=DATASETS.curie("language"), + model_uri=DATASETS.language, + domain=None, + range=Optional[str], +) + +slots.publisher = Slot( + uri=DCTERMS.publisher, + name="publisher", + curie=DCTERMS.curie("publisher"), + model_uri=DATASETS.publisher, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.issued = Slot( + uri=DCTERMS.issued, + name="issued", + curie=DCTERMS.curie("issued"), + model_uri=DATASETS.issued, + domain=None, + range=Optional[Union[str, XSDDateTime]], +) + +slots.page = Slot( + uri=DCAT.landingPage, + name="page", + curie=DCAT.curie("landingPage"), + model_uri=DATASETS.page, + domain=None, + range=Optional[str], +) + +slots.dialect = Slot( + uri=CSVW.dialect, + name="dialect", + curie=CSVW.curie("dialect"), + model_uri=DATASETS.dialect, + domain=None, + range=Optional[str], +) + +slots.bytes = Slot( + uri=DCAT.byteSize, + name="bytes", + curie=DCAT.curie("byteSize"), + model_uri=DATASETS.bytes, + domain=None, + range=Optional[int], +) + +slots.path = Slot( + uri=DATASETS.path, + name="path", + curie=DATASETS.curie("path"), + model_uri=DATASETS.path, + domain=None, + range=Optional[str], +) + +slots.download_url = Slot( + uri=DCAT.downloadURL, + name="download_url", + curie=DCAT.curie("downloadURL"), + model_uri=DATASETS.download_url, + domain=None, + range=Optional[Union[str, URI]], +) + +slots.format = Slot( + uri=DCTERMS.format, + name="format", + curie=DCTERMS.curie("format"), + model_uri=DATASETS.format, + domain=None, + range=Optional[Union[str, "FormatEnum"]], +) + +slots.compression = Slot( + uri=DATASETS.compression, + name="compression", + curie=DATASETS.curie("compression"), + model_uri=DATASETS.compression, + domain=None, + range=Optional[str], +) + +slots.encoding = Slot( + uri=DATASETS.encoding, + name="encoding", + curie=DATASETS.curie("encoding"), + model_uri=DATASETS.encoding, + domain=None, + range=Optional[str], +) + +slots.hash = Slot( + uri=DATASETS.hash, + name="hash", + curie=DATASETS.curie("hash"), + model_uri=DATASETS.hash, + domain=None, + range=Optional[str], +) + +slots.sha256 = Slot( + uri=DATASETS.sha256, + name="sha256", + curie=DATASETS.curie("sha256"), + model_uri=DATASETS.sha256, + domain=None, + range=Optional[str], +) + +slots.md5 = Slot( + uri=DATASETS.md5, name="md5", curie=DATASETS.curie("md5"), model_uri=DATASETS.md5, domain=None, range=Optional[str] +) + +slots.media_type = Slot( + uri=DCAT.mediaType, + name="media_type", + curie=DCAT.curie("mediaType"), + model_uri=DATASETS.media_type, + domain=None, + range=Optional[str], +) + +slots.conforms_to = Slot( + uri=DCTERMS.conformsTo, + name="conforms_to", + curie=DCTERMS.curie("conformsTo"), + model_uri=DATASETS.conforms_to, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.conforms_to_schema = Slot( + uri=DATASETS.conforms_to_schema, + name="conforms_to_schema", + curie=DATASETS.curie("conforms_to_schema"), + model_uri=DATASETS.conforms_to_schema, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.conforms_to_class = Slot( + uri=DATASETS.conforms_to_class, + name="conforms_to_class", + curie=DATASETS.curie("conforms_to_class"), + model_uri=DATASETS.conforms_to_class, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.profile = Slot( + uri=DATASETS.profile, + name="profile", + curie=DATASETS.curie("profile"), + model_uri=DATASETS.profile, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.keywords = Slot( + uri=DCAT.keyword, + name="keywords", + curie=DCAT.curie("keyword"), + model_uri=DATASETS.keywords, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.themes = Slot( + uri=DCAT.theme, + name="themes", + curie=DCAT.curie("theme"), + model_uri=DATASETS.themes, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.resources = Slot( + uri=DCAT.distribution, + name="resources", + curie=DCAT.curie("distribution"), + model_uri=DATASETS.resources, + domain=None, + range=Optional[Union[Union[str, DataResourceId], list[Union[str, DataResourceId]]]], +) + +slots.test_roles = Slot( + uri=DATASETS.test_roles, + name="test_roles", + curie=DATASETS.curie("test_roles"), + model_uri=DATASETS.test_roles, + domain=None, + range=Optional[Union[Union[str, "TestRole"], list[Union[str, "TestRole"]]]], +) + +slots.created_by = Slot( + uri=PAV.createdBy, + name="created_by", + curie=PAV.curie("createdBy"), + model_uri=DATASETS.created_by, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.created_on = Slot( + uri=PAV.createdOn, + name="created_on", + curie=PAV.curie("createdOn"), + model_uri=DATASETS.created_on, + domain=None, + range=Optional[Union[str, XSDDateTime]], +) + +slots.last_updated_on = Slot( + uri=PAV.lastUpdatedOn, + name="last_updated_on", + curie=PAV.curie("lastUpdatedOn"), + model_uri=DATASETS.last_updated_on, + domain=None, + range=Optional[Union[str, XSDDateTime]], +) + +slots.modified_by = Slot( + uri=OSLC.modifiedBy, + name="modified_by", + curie=OSLC.curie("modifiedBy"), + model_uri=DATASETS.modified_by, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.status = Slot( + uri=BIBO.status, + name="status", + curie=BIBO.curie("status"), + model_uri=DATASETS.status, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.license = Slot( + uri=DCTERMS.license, + name="license", + curie=DCTERMS.curie("license"), + model_uri=DATASETS.license, + domain=None, + range=Optional[str], +) + +slots.version = Slot( + uri=PAV.version, + name="version", + curie=PAV.curie("version"), + model_uri=DATASETS.version, + domain=None, + range=Optional[str], +) + +slots.was_derived_from = Slot( + uri=PROV.wasDerivedFrom, + name="was_derived_from", + curie=PROV.curie("wasDerivedFrom"), + model_uri=DATASETS.was_derived_from, + domain=None, + range=Optional[str], +) + +slots.formatDialect__comment_prefix = Slot( + uri=DATASETS.comment_prefix, + name="formatDialect__comment_prefix", + curie=DATASETS.curie("comment_prefix"), + model_uri=DATASETS.formatDialect__comment_prefix, + domain=None, + range=Optional[str], +) + +slots.formatDialect__delimiter = Slot( + uri=DATASETS.delimiter, + name="formatDialect__delimiter", + curie=DATASETS.curie("delimiter"), + model_uri=DATASETS.formatDialect__delimiter, + domain=None, + range=Optional[str], +) + +slots.formatDialect__double_quote = Slot( + uri=DATASETS.double_quote, + name="formatDialect__double_quote", + curie=DATASETS.curie("double_quote"), + model_uri=DATASETS.formatDialect__double_quote, + domain=None, + range=Optional[str], +) + +slots.formatDialect__header = Slot( + uri=DATASETS.header, + name="formatDialect__header", + curie=DATASETS.curie("header"), + model_uri=DATASETS.formatDialect__header, + domain=None, + range=Optional[str], +) + +slots.formatDialect__quote_char = Slot( + uri=DATASETS.quote_char, + name="formatDialect__quote_char", + curie=DATASETS.curie("quote_char"), + model_uri=DATASETS.formatDialect__quote_char, + domain=None, + range=Optional[str], +) diff --git a/linkml_runtime/linkml_model/extensions.py b/linkml_runtime/linkml_model/extensions.py index b7870953..8179a550 100644 --- a/linkml_runtime/linkml_model/extensions.py +++ b/linkml_runtime/linkml_model/extensions.py @@ -20,12 +20,13 @@ version = "2.0.0" # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") DEFAULT_ = LINKML # Types + # Class references class ExtensionTag(URIorCURIE): pass @@ -33,11 +34,13 @@ class ExtensionTag(URIorCURIE): AnyValue = Any + @dataclass class Extension(YAMLRoot): """ a tag/value pair used to add non-model information to an entry """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Extension"] @@ -47,7 +50,9 @@ class Extension(YAMLRoot): tag: Union[str, ExtensionTag] = None value: Union[dict, AnyValue] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, "Extension"]], list[Union[dict, "Extension"]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, "Extension"]], list[Union[dict, "Extension"]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self._is_empty(self.tag): @@ -65,6 +70,7 @@ class Extensible(YAMLRoot): """ mixin for classes that support extension """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Extensible"] @@ -72,7 +78,9 @@ class Extensible(YAMLRoot): class_name: ClassVar[str] = "extensible" class_model_uri: ClassVar[URIRef] = LINKML.Extensible - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self._normalize_inlined_as_dict(slot_name="extensions", slot_type=Extension, key_name="tag", keyed=True) @@ -87,11 +95,30 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.extensions = Slot(uri=LINKML.extensions, name="extensions", curie=LINKML.curie('extensions'), - model_uri=LINKML.extensions, domain=None, range=Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]]) - -slots.extension_tag = Slot(uri=LINKML.tag, name="extension_tag", curie=LINKML.curie('tag'), - model_uri=LINKML.extension_tag, domain=Extension, range=Union[str, ExtensionTag]) -slots.extension_value = Slot(uri=LINKML.value, name="extension_value", curie=LINKML.curie('value'), - model_uri=LINKML.extension_value, domain=Extension, range=Union[dict, AnyValue]) +slots.extensions = Slot( + uri=LINKML.extensions, + name="extensions", + curie=LINKML.curie("extensions"), + model_uri=LINKML.extensions, + domain=None, + range=Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]], +) + +slots.extension_tag = Slot( + uri=LINKML.tag, + name="extension_tag", + curie=LINKML.curie("tag"), + model_uri=LINKML.extension_tag, + domain=Extension, + range=Union[str, ExtensionTag], +) + +slots.extension_value = Slot( + uri=LINKML.value, + name="extension_value", + curie=LINKML.curie("value"), + model_uri=LINKML.extension_value, + domain=Extension, + range=Union[dict, AnyValue], +) diff --git a/linkml_runtime/linkml_model/linkml_files.py b/linkml_runtime/linkml_model/linkml_files.py index 1576eb7b..4299c4b7 100644 --- a/linkml_runtime/linkml_model/linkml_files.py +++ b/linkml_runtime/linkml_model/linkml_files.py @@ -1,8 +1,8 @@ -from pathlib import Path +from dataclasses import dataclass from enum import Enum, auto -from typing import Optional, Union, NamedTuple +from pathlib import Path +from typing import NamedTuple, Optional, Union from urllib.parse import urljoin -from dataclasses import dataclass import requests from rdflib import Namespace @@ -24,7 +24,8 @@ def _generate_next_value_(name, start, count, last_values): class Source(_AutoName): - """ LinkML package source name """ + """LinkML package source name""" + META = auto() TYPES = auto() MAPPINGS = auto() @@ -33,7 +34,8 @@ class Source(_AutoName): class Format(_AutoName): - """ LinkML package formats """ + """LinkML package formats""" + EXCEL = auto() GRAPHQL = auto() JSON = auto() @@ -55,48 +57,51 @@ class Format(_AutoName): SQLSCHEMA = auto() YAML = auto() + @dataclass class FormatPath: path: str extension: str - def model_path(self, model:str) -> Path: + def model_path(self, model: str) -> Path: return (Path(self.path) / model).with_suffix(self.extension) + class _Path: - """ LinkML Relative paths""" - EXCEL = FormatPath("excel","xlsx" ) - GRAPHQL = FormatPath("graphql","graphql" ) - JSON = FormatPath("json","json" ) - JSONLD = FormatPath("jsonld","context.jsonld" ) - JSON_SCHEMA = FormatPath("jsonschema", "schema.json" ) - NATIVE_JSONLD = FormatPath("jsonld", "context.jsonld" ) - NATIVE_RDF = FormatPath("rdf","ttl" ) - NATIVE_SHEXC = FormatPath("shex","shex" ) - NATIVE_SHEXJ = FormatPath("shex","shexj" ) - OWL = FormatPath("owl","owl.ttl" ) - PREFIXMAP = FormatPath('prefixmap','yaml' ) - PROTOBUF = FormatPath("protobuf","proto" ) - PYTHON = FormatPath("","py" ) - RDF = FormatPath("rdf","ttl" ) - SHACL = FormatPath("shacl","shacl.ttl" ) - SHEXC = FormatPath("shex","shex" ) - SHEXJ = FormatPath("shex","shexj" ) - SQLDDL = FormatPath("sqlddl","sql" ) - SQLSCHEMA = FormatPath("sqlschema","sql" ) - YAML = FormatPath((Path("model") / "schema").as_posix(),"yaml" ) + """LinkML Relative paths""" + + EXCEL = FormatPath("excel", "xlsx") + GRAPHQL = FormatPath("graphql", "graphql") + JSON = FormatPath("json", "json") + JSONLD = FormatPath("jsonld", "context.jsonld") + JSON_SCHEMA = FormatPath("jsonschema", "schema.json") + NATIVE_JSONLD = FormatPath("jsonld", "context.jsonld") + NATIVE_RDF = FormatPath("rdf", "ttl") + NATIVE_SHEXC = FormatPath("shex", "shex") + NATIVE_SHEXJ = FormatPath("shex", "shexj") + OWL = FormatPath("owl", "owl.ttl") + PREFIXMAP = FormatPath("prefixmap", "yaml") + PROTOBUF = FormatPath("protobuf", "proto") + PYTHON = FormatPath("", "py") + RDF = FormatPath("rdf", "ttl") + SHACL = FormatPath("shacl", "shacl.ttl") + SHEXC = FormatPath("shex", "shex") + SHEXJ = FormatPath("shex", "shexj") + SQLDDL = FormatPath("sqlddl", "sql") + SQLSCHEMA = FormatPath("sqlschema", "sql") + YAML = FormatPath((Path("model") / "schema").as_posix(), "yaml") @classmethod def items(cls) -> dict[str, FormatPath]: - return {k:v for k,v in cls.__dict__.items() if not k.startswith('_')} + return {k: v for k, v in cls.__dict__.items() if not k.startswith("_")} @classmethod - def get(cls, item:Union[str,Format]) -> FormatPath: + def get(cls, item: Union[str, Format]) -> FormatPath: if isinstance(item, Format): item = item.name.upper() return getattr(cls, item) - def __class_getitem__(cls, item:str) -> FormatPath: + def __class_getitem__(cls, item: str) -> FormatPath: return getattr(cls, item) @@ -108,14 +113,15 @@ def __class_getitem__(cls, item:str) -> FormatPath: Format.PROTOBUF, Format.SHACL, Format.SQLDDL, - Format.SQLSCHEMA + Format.SQLSCHEMA, ) class ReleaseTag(_AutoName): - """ Release tags + """Release tags LATEST - the absolute latest in the supplied branch - CURRENT - the latest _released_ version in the supplied branch """ + CURRENT - the latest _released_ version in the supplied branch""" + LATEST = auto() CURRENT = auto() @@ -137,12 +143,12 @@ def _build_path(source: Source, fmt: Format) -> PathParts: def _build_loc(base: str, source: Source, fmt: Format) -> str: """A github location""" # urls are always forward slash separated, so hardcoding is appropriate here - path = '/'.join(_build_path(source, fmt)) - return urljoin(base, path).replace('blob/', '') + path = "/".join(_build_path(source, fmt)) + return urljoin(base, path).replace("blob/", "") def URL_FOR(source: Source, fmt: Format) -> str: - """ Return the URL to retrieve source in format """ + """Return the URL to retrieve source in format""" fmt_path: FormatPath = _Path.get(fmt.name) return f"{LINKML_URL_BASE}{source.value}.{fmt_path.extension}" @@ -152,14 +158,16 @@ def LOCAL_PATH_FOR(source: Source, fmt: Format) -> str: def GITHUB_IO_PATH_FOR(source: Source, fmt: Format, version="latest") -> str: - path = '/'.join([version, 'linkml_model', *_build_path(source, fmt)]) + path = "/".join([version, "linkml_model", *_build_path(source, fmt)]) return urljoin(GITHUB_IO_BASE, path) -def GITHUB_PATH_FOR(source: Source, - fmt: Format, - release: Optional[Union[ReleaseTag, str]] = ReleaseTag.CURRENT, - branch: Optional[str] = "main") -> str: +def GITHUB_PATH_FOR( + source: Source, + fmt: Format, + release: Optional[Union[ReleaseTag, str]] = ReleaseTag.CURRENT, + branch: Optional[str] = "main", +) -> str: def do_request(url) -> object: resp = requests.get(url) if resp.ok: @@ -169,7 +177,7 @@ def do_request(url) -> object: def tag_to_commit(tag: str) -> str: tags = do_request(f"{GITHUB_API_BASE}tags?per_page=100") for tagent in tags: - if tagent['name'] == tag: + if tagent["name"] == tag: return _build_loc(f"{GITHUB_BASE}blob/{tagent['commit']['sha']}/", source, fmt) raise ValueError(f"Tag: {tag} not found!") @@ -178,13 +186,13 @@ def tag_to_commit(tag: str) -> str: # Return the absolute latest entry for branch if release is ReleaseTag.LATEST or (release is ReleaseTag.CURRENT and branch != "main"): - path = '/'.join([branch, 'linkml_model', *_build_path(source, fmt)]) + path = "/".join([branch, "linkml_model", *_build_path(source, fmt)]) return urljoin(GITHUB_BASE, path) # Return the latest published version elif release is ReleaseTag.CURRENT: release = do_request(f"{GITHUB_API_BASE}releases/latest") - return tag_to_commit(release['tag_name']) + return tag_to_commit(release["tag_name"]) # Return a specific tag else: @@ -212,7 +220,9 @@ def url(self) -> str: def file(self) -> str: return LOCAL_PATH_FOR(self._model, self._format) - def github_loc(self, tag: Optional[str] = None, branch: Optional[str] = None, release: ReleaseTag = None) -> str: + def github_loc( + self, tag: Optional[str] = None, branch: Optional[str] = None, release: ReleaseTag = None + ) -> str: if not tag and not branch and not release: return GITHUB_IO_PATH_FOR(self._model, self._format) if tag: diff --git a/linkml_runtime/linkml_model/mappings.py b/linkml_runtime/linkml_model/mappings.py index 39f14117..b9888b86 100644 --- a/linkml_runtime/linkml_model/mappings.py +++ b/linkml_runtime/linkml_model/mappings.py @@ -8,21 +8,21 @@ from typing import Optional, Union -from linkml_runtime.utils.slot import Slot from linkml_runtime.utils.curienamespace import CurieNamespace from linkml_runtime.utils.metamodelcore import URIorCURIE +from linkml_runtime.utils.slot import Slot metamodel_version = "1.7.0" version = "2.0.0" # Namespaces -IAO = CurieNamespace('IAO', 'http://purl.obolibrary.org/obo/IAO_') -OIO = CurieNamespace('OIO', 'http://www.geneontology.org/formats/oboInOwl#') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +IAO = CurieNamespace("IAO", "http://purl.obolibrary.org/obo/IAO_") +OIO = CurieNamespace("OIO", "http://www.geneontology.org/formats/oboInOwl#") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = LINKML @@ -31,8 +31,6 @@ # Class references - - # Enumerations @@ -40,26 +38,77 @@ class slots: pass -slots.mappings = Slot(uri=SKOS.mappingRelation, name="mappings", curie=SKOS.curie('mappingRelation'), - model_uri=LINKML.mappings, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.exact_mappings = Slot(uri=SKOS.exactMatch, name="exact mappings", curie=SKOS.curie('exactMatch'), - model_uri=LINKML.exact_mappings, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.close_mappings = Slot(uri=SKOS.closeMatch, name="close mappings", curie=SKOS.curie('closeMatch'), - model_uri=LINKML.close_mappings, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.related_mappings = Slot(uri=SKOS.relatedMatch, name="related mappings", curie=SKOS.curie('relatedMatch'), - model_uri=LINKML.related_mappings, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.narrow_mappings = Slot(uri=SKOS.narrowMatch, name="narrow mappings", curie=SKOS.curie('narrowMatch'), - model_uri=LINKML.narrow_mappings, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.broad_mappings = Slot(uri=SKOS.broadMatch, name="broad mappings", curie=SKOS.curie('broadMatch'), - model_uri=LINKML.broad_mappings, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.deprecated_element_has_exact_replacement = Slot(uri=LINKML.deprecated_element_has_exact_replacement, name="deprecated element has exact replacement", curie=LINKML.curie('deprecated_element_has_exact_replacement'), - model_uri=LINKML.deprecated_element_has_exact_replacement, domain=None, range=Optional[Union[str, URIorCURIE]], mappings = [IAO["0100001"]]) -slots.deprecated_element_has_possible_replacement = Slot(uri=LINKML.deprecated_element_has_possible_replacement, name="deprecated element has possible replacement", curie=LINKML.curie('deprecated_element_has_possible_replacement'), - model_uri=LINKML.deprecated_element_has_possible_replacement, domain=None, range=Optional[Union[str, URIorCURIE]], mappings = [OIO["consider"]]) +slots.mappings = Slot( + uri=SKOS.mappingRelation, + name="mappings", + curie=SKOS.curie("mappingRelation"), + model_uri=LINKML.mappings, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.exact_mappings = Slot( + uri=SKOS.exactMatch, + name="exact mappings", + curie=SKOS.curie("exactMatch"), + model_uri=LINKML.exact_mappings, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.close_mappings = Slot( + uri=SKOS.closeMatch, + name="close mappings", + curie=SKOS.curie("closeMatch"), + model_uri=LINKML.close_mappings, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.related_mappings = Slot( + uri=SKOS.relatedMatch, + name="related mappings", + curie=SKOS.curie("relatedMatch"), + model_uri=LINKML.related_mappings, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.narrow_mappings = Slot( + uri=SKOS.narrowMatch, + name="narrow mappings", + curie=SKOS.curie("narrowMatch"), + model_uri=LINKML.narrow_mappings, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.broad_mappings = Slot( + uri=SKOS.broadMatch, + name="broad mappings", + curie=SKOS.curie("broadMatch"), + model_uri=LINKML.broad_mappings, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.deprecated_element_has_exact_replacement = Slot( + uri=LINKML.deprecated_element_has_exact_replacement, + name="deprecated element has exact replacement", + curie=LINKML.curie("deprecated_element_has_exact_replacement"), + model_uri=LINKML.deprecated_element_has_exact_replacement, + domain=None, + range=Optional[Union[str, URIorCURIE]], + mappings=[IAO["0100001"]], +) + +slots.deprecated_element_has_possible_replacement = Slot( + uri=LINKML.deprecated_element_has_possible_replacement, + name="deprecated element has possible replacement", + curie=LINKML.curie("deprecated_element_has_possible_replacement"), + model_uri=LINKML.deprecated_element_has_possible_replacement, + domain=None, + range=Optional[Union[str, URIorCURIE]], + mappings=[OIO["consider"]], +) diff --git a/linkml_runtime/linkml_model/meta.py b/linkml_runtime/linkml_model/meta.py index 8af4f410..71be3aef 100644 --- a/linkml_runtime/linkml_model/meta.py +++ b/linkml_runtime/linkml_model/meta.py @@ -50,34 +50,35 @@ version = None # Namespaces -IAO = CurieNamespace('IAO', 'http://purl.obolibrary.org/obo/IAO_') -NCIT = CurieNamespace('NCIT', 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#') -OIO = CurieNamespace('OIO', 'http://www.geneontology.org/formats/oboInOwl#') -SIO = CurieNamespace('SIO', 'http://semanticscience.org/resource/SIO_') -BIBO = CurieNamespace('bibo', 'http://purl.org/ontology/bibo/') -CDISC = CurieNamespace('cdisc', 'http://rdf.cdisc.org/mms#') -DCTERMS = CurieNamespace('dcterms', 'http://purl.org/dc/terms/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -OSLC = CurieNamespace('oslc', 'http://open-services.net/ns/core#') -OWL = CurieNamespace('owl', 'http://www.w3.org/2002/07/owl#') -PAV = CurieNamespace('pav', 'http://purl.org/pav/') -PROV = CurieNamespace('prov', 'http://www.w3.org/ns/prov#') -QB = CurieNamespace('qb', 'http://purl.org/linked-data/cube#') -QUDT = CurieNamespace('qudt', 'http://qudt.org/schema/qudt/') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SH = CurieNamespace('sh', 'http://www.w3.org/ns/shacl#') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -SKOSXL = CurieNamespace('skosxl', 'http://www.w3.org/2008/05/skos-xl#') -SWRL = CurieNamespace('swrl', 'http://www.w3.org/2003/11/swrl#') -VANN = CurieNamespace('vann', 'https://vocab.org/vann/') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +IAO = CurieNamespace("IAO", "http://purl.obolibrary.org/obo/IAO_") +NCIT = CurieNamespace("NCIT", "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#") +OIO = CurieNamespace("OIO", "http://www.geneontology.org/formats/oboInOwl#") +SIO = CurieNamespace("SIO", "http://semanticscience.org/resource/SIO_") +BIBO = CurieNamespace("bibo", "http://purl.org/ontology/bibo/") +CDISC = CurieNamespace("cdisc", "http://rdf.cdisc.org/mms#") +DCTERMS = CurieNamespace("dcterms", "http://purl.org/dc/terms/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +OSLC = CurieNamespace("oslc", "http://open-services.net/ns/core#") +OWL = CurieNamespace("owl", "http://www.w3.org/2002/07/owl#") +PAV = CurieNamespace("pav", "http://purl.org/pav/") +PROV = CurieNamespace("prov", "http://www.w3.org/ns/prov#") +QB = CurieNamespace("qb", "http://purl.org/linked-data/cube#") +QUDT = CurieNamespace("qudt", "http://qudt.org/schema/qudt/") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SH = CurieNamespace("sh", "http://www.w3.org/ns/shacl#") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +SKOSXL = CurieNamespace("skosxl", "http://www.w3.org/2008/05/skos-xl#") +SWRL = CurieNamespace("swrl", "http://www.w3.org/2003/11/swrl#") +VANN = CurieNamespace("vann", "https://vocab.org/vann/") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = LINKML # Types + # Class references class ElementName(extended_str): pass @@ -141,11 +142,13 @@ class TypeMappingFramework(extended_str): Anything = Any + @dataclass(repr=False) class CommonMetadata(YAMLRoot): """ Generic metadata shared across definitions """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["CommonMetadata"] @@ -154,7 +157,11 @@ class CommonMetadata(YAMLRoot): class_model_uri: ClassVar[URIRef] = LINKML.CommonMetadata description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -170,7 +177,9 @@ class CommonMetadata(YAMLRoot): deprecated_element_has_exact_replacement: Optional[Union[str, URIorCURIE]] = None deprecated_element_has_possible_replacement: Optional[Union[str, URIorCURIE]] = None aliases: Optional[Union[str, list[str]]] = empty_list() - structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = empty_list() + structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = ( + empty_list() + ) mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() exact_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() close_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() @@ -191,7 +200,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -235,17 +246,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -309,6 +328,7 @@ class Element(YAMLRoot): """ A named element in the model """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Element"] @@ -320,14 +340,24 @@ class Element(YAMLRoot): id_prefixes: Optional[Union[Union[str, NCName], list[Union[str, NCName]]]] = empty_list() id_prefixes_are_closed: Optional[Union[bool, Bool]] = None definition_uri: Optional[Union[str, URIorCURIE]] = None - local_names: Optional[Union[dict[Union[str, LocalNameLocalNameSource], Union[dict, "LocalName"]], list[Union[dict, "LocalName"]]]] = empty_dict() + local_names: Optional[ + Union[dict[Union[str, LocalNameLocalNameSource], Union[dict, "LocalName"]], list[Union[dict, "LocalName"]]] + ] = empty_dict() conforms_to: Optional[str] = None implements: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() instantiates: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -343,7 +373,9 @@ class Element(YAMLRoot): deprecated_element_has_exact_replacement: Optional[Union[str, URIorCURIE]] = None deprecated_element_has_possible_replacement: Optional[Union[str, URIorCURIE]] = None aliases: Optional[Union[str, list[str]]] = empty_list() - structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = empty_list() + structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = ( + empty_list() + ) mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() exact_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() close_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() @@ -376,7 +408,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.definition_uri is not None and not isinstance(self.definition_uri, URIorCURIE): self.definition_uri = URIorCURIE(self.definition_uri) - self._normalize_inlined_as_dict(slot_name="local_names", slot_type=LocalName, key_name="local_name_source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="local_names", slot_type=LocalName, key_name="local_name_source", keyed=True + ) if self.conforms_to is not None and not isinstance(self.conforms_to, str): self.conforms_to = str(self.conforms_to) @@ -396,7 +430,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -440,17 +476,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -514,6 +558,7 @@ class SchemaDefinition(Element): """ A collection of definitions that make up a schema or a data model. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["SchemaDefinition"] @@ -526,23 +571,42 @@ class SchemaDefinition(Element): version: Optional[str] = None imports: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() license: Optional[str] = None - prefixes: Optional[Union[dict[Union[str, PrefixPrefixPrefix], Union[dict, "Prefix"]], list[Union[dict, "Prefix"]]]] = empty_dict() + prefixes: Optional[ + Union[dict[Union[str, PrefixPrefixPrefix], Union[dict, "Prefix"]], list[Union[dict, "Prefix"]]] + ] = empty_dict() emit_prefixes: Optional[Union[Union[str, NCName], list[Union[str, NCName]]]] = empty_list() default_curi_maps: Optional[Union[str, list[str]]] = empty_list() default_prefix: Optional[str] = None default_range: Optional[Union[str, TypeDefinitionName]] = None - subsets: Optional[Union[dict[Union[str, SubsetDefinitionName], Union[dict, "SubsetDefinition"]], list[Union[dict, "SubsetDefinition"]]]] = empty_dict() - types: Optional[Union[dict[Union[str, TypeDefinitionName], Union[dict, "TypeDefinition"]], list[Union[dict, "TypeDefinition"]]]] = empty_dict() - enums: Optional[Union[dict[Union[str, EnumDefinitionName], Union[dict, "EnumDefinition"]], list[Union[dict, "EnumDefinition"]]]] = empty_dict() - slots: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, "SlotDefinition"]], list[Union[dict, "SlotDefinition"]]]] = empty_dict() - classes: Optional[Union[dict[Union[str, ClassDefinitionName], Union[dict, "ClassDefinition"]], list[Union[dict, "ClassDefinition"]]]] = empty_dict() + subsets: Optional[ + Union[ + dict[Union[str, SubsetDefinitionName], Union[dict, "SubsetDefinition"]], + list[Union[dict, "SubsetDefinition"]], + ] + ] = empty_dict() + types: Optional[ + Union[dict[Union[str, TypeDefinitionName], Union[dict, "TypeDefinition"]], list[Union[dict, "TypeDefinition"]]] + ] = empty_dict() + enums: Optional[ + Union[dict[Union[str, EnumDefinitionName], Union[dict, "EnumDefinition"]], list[Union[dict, "EnumDefinition"]]] + ] = empty_dict() + slots: Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, "SlotDefinition"]], list[Union[dict, "SlotDefinition"]]] + ] = empty_dict() + classes: Optional[ + Union[ + dict[Union[str, ClassDefinitionName], Union[dict, "ClassDefinition"]], list[Union[dict, "ClassDefinition"]] + ] + ] = empty_dict() metamodel_version: Optional[str] = None source_file: Optional[str] = None source_file_date: Optional[Union[str, XSDDateTime]] = None source_file_size: Optional[int] = None generation_date: Optional[Union[str, XSDDateTime]] = None slot_names_unique: Optional[Union[bool, Bool]] = None - settings: Optional[Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]]] = empty_dict() + settings: Optional[ + Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]] + ] = empty_dict() bindings: Optional[Union[Union[dict, "EnumBinding"], list[Union[dict, "EnumBinding"]]]] = empty_list() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): @@ -626,7 +690,16 @@ class AnonymousTypeExpression(YAMLRoot): """ A type expression that is not a top-level named type definition. Used for nesting. """ - _inherited_slots: ClassVar[list[str]] = ["pattern", "structured_pattern", "equals_string", "equals_string_in", "equals_number", "minimum_value", "maximum_value"] + + _inherited_slots: ClassVar[list[str]] = [ + "pattern", + "structured_pattern", + "equals_string", + "equals_string_in", + "equals_number", + "minimum_value", + "maximum_value", + ] class_class_uri: ClassVar[URIRef] = LINKML["AnonymousTypeExpression"] class_class_curie: ClassVar[str] = "linkml:AnonymousTypeExpression" @@ -642,10 +715,18 @@ class AnonymousTypeExpression(YAMLRoot): equals_number: Optional[int] = None minimum_value: Optional[Union[dict, Anything]] = None maximum_value: Optional[Union[dict, Anything]] = None - none_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() - any_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() - all_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() + none_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]] + ] = empty_list() + any_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.pattern is not None and not isinstance(self.pattern, str): @@ -672,19 +753,28 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.none_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.any_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.all_of + ] super().__post_init__(**kwargs) @@ -694,7 +784,19 @@ class TypeDefinition(Element): """ an element that whose instances are atomic scalar values that can be mapped to primitive types """ - _inherited_slots: ClassVar[list[str]] = ["base", "uri", "repr", "pattern", "structured_pattern", "equals_string", "equals_string_in", "equals_number", "minimum_value", "maximum_value"] + + _inherited_slots: ClassVar[list[str]] = [ + "base", + "uri", + "repr", + "pattern", + "structured_pattern", + "equals_string", + "equals_string_in", + "equals_number", + "minimum_value", + "maximum_value", + ] class_class_uri: ClassVar[URIRef] = LINKML["TypeDefinition"] class_class_curie: ClassVar[str] = "linkml:TypeDefinition" @@ -716,10 +818,18 @@ class TypeDefinition(Element): equals_number: Optional[int] = None minimum_value: Optional[Union[dict, Anything]] = None maximum_value: Optional[Union[dict, Anything]] = None - none_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = empty_list() - any_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = empty_list() - all_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = empty_list() + none_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]] + ] = empty_list() + any_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, AnonymousTypeExpression], list[Union[dict, AnonymousTypeExpression]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self._is_empty(self.name): @@ -767,19 +877,28 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.none_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.any_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.all_of + ] super().__post_init__(**kwargs) @@ -789,6 +908,7 @@ class SubsetDefinition(Element): """ an element that can be used to group other metamodel elements """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["SubsetDefinition"] @@ -812,6 +932,7 @@ class Definition(Element): """ abstract base class for core metaclasses """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Definition"] @@ -861,6 +982,7 @@ class AnonymousEnumExpression(YAMLRoot): """ An enum_expression that is not named """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["AnonymousEnumExpression"] @@ -872,9 +994,18 @@ class AnonymousEnumExpression(YAMLRoot): code_set_tag: Optional[str] = None code_set_version: Optional[str] = None pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None - permissible_values: Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]] = empty_dict() - include: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = empty_list() - minus: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = empty_list() + permissible_values: Optional[ + Union[ + dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], + list[Union[dict, "PermissibleValue"]], + ] + ] = empty_dict() + include: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = ( + empty_list() + ) + minus: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = ( + empty_list() + ) inherits: Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]] = empty_list() reachable_from: Optional[Union[dict, "ReachabilityQuery"]] = None matches: Optional[Union[dict, "MatchQuery"]] = None @@ -893,15 +1024,21 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.pv_formula is not None and not isinstance(self.pv_formula, PvFormulaOptions): self.pv_formula = PvFormulaOptions(self.pv_formula) - self._normalize_inlined_as_dict(slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True) + self._normalize_inlined_as_dict( + slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True + ) if not isinstance(self.include, list): self.include = [self.include] if self.include is not None else [] - self.include = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include] + self.include = [ + v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include + ] if not isinstance(self.minus, list): self.minus = [self.minus] if self.minus is not None else [] - self.minus = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.minus] + self.minus = [ + v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.minus + ] if not isinstance(self.inherits, list): self.inherits = [self.inherits] if self.inherits is not None else [] @@ -925,6 +1062,7 @@ class EnumDefinition(Definition): """ an element whose instances must be drawn from a specified set of permissible values """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["EnumDefinition"] @@ -938,9 +1076,18 @@ class EnumDefinition(Definition): code_set_tag: Optional[str] = None code_set_version: Optional[str] = None pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None - permissible_values: Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]] = empty_dict() - include: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = empty_list() - minus: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = empty_list() + permissible_values: Optional[ + Union[ + dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], + list[Union[dict, "PermissibleValue"]], + ] + ] = empty_dict() + include: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = ( + empty_list() + ) + minus: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = ( + empty_list() + ) inherits: Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]] = empty_list() reachable_from: Optional[Union[dict, "ReachabilityQuery"]] = None matches: Optional[Union[dict, "MatchQuery"]] = None @@ -967,15 +1114,21 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.pv_formula is not None and not isinstance(self.pv_formula, PvFormulaOptions): self.pv_formula = PvFormulaOptions(self.pv_formula) - self._normalize_inlined_as_dict(slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True) + self._normalize_inlined_as_dict( + slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True + ) if not isinstance(self.include, list): self.include = [self.include] if self.include is not None else [] - self.include = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include] + self.include = [ + v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include + ] if not isinstance(self.minus, list): self.minus = [self.minus] if self.minus is not None else [] - self.minus = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.minus] + self.minus = [ + v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.minus + ] if not isinstance(self.inherits, list): self.inherits = [self.inherits] if self.inherits is not None else [] @@ -999,6 +1152,7 @@ class EnumBinding(YAMLRoot): """ A binding of a slot or a class to a permissible value from an enumeration. """ + _inherited_slots: ClassVar[list[str]] = ["range"] class_class_uri: ClassVar[URIRef] = LINKML["EnumBinding"] @@ -1010,10 +1164,18 @@ class EnumBinding(YAMLRoot): obligation_level: Optional[Union[str, "ObligationLevelEnum"]] = None binds_value_of: Optional[str] = None pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -1029,7 +1191,9 @@ class EnumBinding(YAMLRoot): deprecated_element_has_exact_replacement: Optional[Union[str, URIorCURIE]] = None deprecated_element_has_possible_replacement: Optional[Union[str, URIorCURIE]] = None aliases: Optional[Union[str, list[str]]] = empty_list() - structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = empty_list() + structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = ( + empty_list() + ) mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() exact_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() close_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() @@ -1066,7 +1230,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -1110,17 +1276,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -1185,6 +1359,7 @@ class MatchQuery(YAMLRoot): A query that is used on an enum expression to dynamically obtain a set of permissivle values via a query that matches on properties of the external concepts. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["MatchQuery"] @@ -1211,6 +1386,7 @@ class ReachabilityQuery(YAMLRoot): A query that is used on an enum expression to dynamically obtain a set of permissible values via walking from a set of source nodes to a set of descendants or ancestors over a set of relationship types. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["ReachabilityQuery"] @@ -1255,6 +1431,7 @@ class StructuredAlias(YAMLRoot): object that contains meta data about a synonym or alias including where it came from (source) and its scope (narrow, broad, etc.) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SKOSXL["Label"] @@ -1266,10 +1443,18 @@ class StructuredAlias(YAMLRoot): predicate: Optional[Union[str, "AliasPredicateEnum"]] = None categories: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() contexts: Optional[Union[Union[str, URI], list[Union[str, URI]]]] = empty_list() - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -1285,7 +1470,9 @@ class StructuredAlias(YAMLRoot): deprecated_element_has_exact_replacement: Optional[Union[str, URIorCURIE]] = None deprecated_element_has_possible_replacement: Optional[Union[str, URIorCURIE]] = None aliases: Optional[Union[str, list[str]]] = empty_list() - structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = empty_list() + structured_aliases: Optional[Union[Union[dict, "StructuredAlias"], list[Union[dict, "StructuredAlias"]]]] = ( + empty_list() + ) mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() exact_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() close_mappings: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() @@ -1325,7 +1512,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -1369,17 +1558,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -1438,6 +1635,7 @@ class Expression(YAMLRoot): """ general mixin for any class that can represent some form of expression """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Expression"] @@ -1451,7 +1649,16 @@ class TypeExpression(Expression): """ An abstract class grouping named types and anonymous type expressions """ - _inherited_slots: ClassVar[list[str]] = ["pattern", "structured_pattern", "equals_string", "equals_string_in", "equals_number", "minimum_value", "maximum_value"] + + _inherited_slots: ClassVar[list[str]] = [ + "pattern", + "structured_pattern", + "equals_string", + "equals_string_in", + "equals_number", + "minimum_value", + "maximum_value", + ] class_class_uri: ClassVar[URIRef] = LINKML["TypeExpression"] class_class_curie: ClassVar[str] = "linkml:TypeExpression" @@ -1467,10 +1674,18 @@ class TypeExpression(Expression): equals_number: Optional[int] = None minimum_value: Optional[Union[dict, Anything]] = None maximum_value: Optional[Union[dict, Anything]] = None - none_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() - any_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() - all_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = empty_list() + none_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]] + ] = empty_list() + any_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.pattern is not None and not isinstance(self.pattern, str): @@ -1497,19 +1712,28 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.none_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.any_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousTypeExpression) else AnonymousTypeExpression(**as_dict(v)) for v in self.all_of + ] super().__post_init__(**kwargs) @@ -1519,6 +1743,7 @@ class EnumExpression(Expression): """ An expression that constrains the range of a slot """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["EnumExpression"] @@ -1530,9 +1755,18 @@ class EnumExpression(Expression): code_set_tag: Optional[str] = None code_set_version: Optional[str] = None pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None - permissible_values: Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]] = empty_dict() - include: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = empty_list() - minus: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = empty_list() + permissible_values: Optional[ + Union[ + dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], + list[Union[dict, "PermissibleValue"]], + ] + ] = empty_dict() + include: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = ( + empty_list() + ) + minus: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = ( + empty_list() + ) inherits: Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]] = empty_list() reachable_from: Optional[Union[dict, "ReachabilityQuery"]] = None matches: Optional[Union[dict, "MatchQuery"]] = None @@ -1551,15 +1785,21 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.pv_formula is not None and not isinstance(self.pv_formula, PvFormulaOptions): self.pv_formula = PvFormulaOptions(self.pv_formula) - self._normalize_inlined_as_dict(slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True) + self._normalize_inlined_as_dict( + slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True + ) if not isinstance(self.include, list): self.include = [self.include] if self.include is not None else [] - self.include = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include] + self.include = [ + v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include + ] if not isinstance(self.minus, list): self.minus = [self.minus] if self.minus is not None else [] - self.minus = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.minus] + self.minus = [ + v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.minus + ] if not isinstance(self.inherits, list): self.inherits = [self.inherits] if self.inherits is not None else [] @@ -1583,6 +1823,7 @@ class AnonymousExpression(YAMLRoot): """ An abstract parent class for any nested expression """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["AnonymousExpression"] @@ -1590,10 +1831,18 @@ class AnonymousExpression(YAMLRoot): class_name: ClassVar[str] = "anonymous_expression" class_model_uri: ClassVar[URIRef] = LINKML.AnonymousExpression - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -1634,7 +1883,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -1678,17 +1929,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -1752,6 +2011,7 @@ class PathExpression(YAMLRoot): """ An expression that describes an abstract path from an object to another through a sequence of slot lookups """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["PathExpression"] @@ -1767,10 +2027,18 @@ class PathExpression(YAMLRoot): reversed: Optional[Union[bool, Bool]] = None traverse: Optional[Union[str, SlotDefinitionName]] = None range_expression: Optional[Union[dict, "AnonymousClassExpression"]] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -1821,7 +2089,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, PathExpression) else PathExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, PathExpression) else PathExpression(**as_dict(v)) for v in self.exactly_one_of + ] if self.reversed is not None and not isinstance(self.reversed, Bool): self.reversed = Bool(self.reversed) @@ -1839,7 +2109,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -1883,17 +2155,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -1957,7 +2237,27 @@ class SlotExpression(Expression): """ an expression that constrains the range of values a slot can take """ - _inherited_slots: ClassVar[list[str]] = ["range", "required", "recommended", "multivalued", "inlined", "inlined_as_list", "minimum_value", "maximum_value", "pattern", "structured_pattern", "value_presence", "equals_string", "equals_string_in", "equals_number", "equals_expression", "exact_cardinality", "minimum_cardinality", "maximum_cardinality"] + + _inherited_slots: ClassVar[list[str]] = [ + "range", + "required", + "recommended", + "multivalued", + "inlined", + "inlined_as_list", + "minimum_value", + "maximum_value", + "pattern", + "structured_pattern", + "value_presence", + "equals_string", + "equals_string_in", + "equals_number", + "equals_expression", + "exact_cardinality", + "minimum_cardinality", + "maximum_cardinality", + ] class_class_uri: ClassVar[URIRef] = LINKML["SlotExpression"] class_class_curie: ClassVar[str] = "linkml:SlotExpression" @@ -1989,10 +2289,18 @@ class SlotExpression(Expression): maximum_cardinality: Optional[int] = None has_member: Optional[Union[dict, "AnonymousSlotExpression"]] = None all_members: Optional[Union[dict, "AnonymousSlotExpression"]] = None - none_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() - any_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() - all_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() + none_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]] + ] = empty_list() + any_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.range is not None and not isinstance(self.range, ElementName): @@ -2068,26 +2376,54 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.none_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.any_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.all_of + ] super().__post_init__(**kwargs) @dataclass(repr=False) class AnonymousSlotExpression(AnonymousExpression): - _inherited_slots: ClassVar[list[str]] = ["range", "required", "recommended", "multivalued", "inlined", "inlined_as_list", "minimum_value", "maximum_value", "pattern", "structured_pattern", "value_presence", "equals_string", "equals_string_in", "equals_number", "equals_expression", "exact_cardinality", "minimum_cardinality", "maximum_cardinality"] + _inherited_slots: ClassVar[list[str]] = [ + "range", + "required", + "recommended", + "multivalued", + "inlined", + "inlined_as_list", + "minimum_value", + "maximum_value", + "pattern", + "structured_pattern", + "value_presence", + "equals_string", + "equals_string_in", + "equals_number", + "equals_expression", + "exact_cardinality", + "minimum_cardinality", + "maximum_cardinality", + ] class_class_uri: ClassVar[URIRef] = LINKML["AnonymousSlotExpression"] class_class_curie: ClassVar[str] = "linkml:AnonymousSlotExpression" @@ -2119,10 +2455,18 @@ class AnonymousSlotExpression(AnonymousExpression): maximum_cardinality: Optional[int] = None has_member: Optional[Union[dict, "AnonymousSlotExpression"]] = None all_members: Optional[Union[dict, "AnonymousSlotExpression"]] = None - none_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() - any_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() - all_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = empty_list() + none_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]] + ] = empty_list() + any_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.range is not None and not isinstance(self.range, ElementName): @@ -2198,19 +2542,28 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.none_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.any_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.all_of + ] super().__post_init__(**kwargs) @@ -2220,7 +2573,40 @@ class SlotDefinition(Definition): """ an element that describes how instances are related to other instances """ - _inherited_slots: ClassVar[list[str]] = ["domain", "array", "inherited", "readonly", "ifabsent", "list_elements_unique", "list_elements_ordered", "shared", "key", "identifier", "designates_type", "role", "relational_role", "range", "required", "recommended", "multivalued", "inlined", "inlined_as_list", "minimum_value", "maximum_value", "pattern", "structured_pattern", "value_presence", "equals_string", "equals_string_in", "equals_number", "equals_expression", "exact_cardinality", "minimum_cardinality", "maximum_cardinality"] + + _inherited_slots: ClassVar[list[str]] = [ + "domain", + "array", + "inherited", + "readonly", + "ifabsent", + "list_elements_unique", + "list_elements_ordered", + "shared", + "key", + "identifier", + "designates_type", + "role", + "relational_role", + "range", + "required", + "recommended", + "multivalued", + "inlined", + "inlined_as_list", + "minimum_value", + "maximum_value", + "pattern", + "structured_pattern", + "value_presence", + "equals_string", + "equals_string_in", + "equals_number", + "equals_expression", + "exact_cardinality", + "minimum_cardinality", + "maximum_cardinality", + ] class_class_uri: ClassVar[URIRef] = LINKML["SlotDefinition"] class_class_curie: ClassVar[str] = "linkml:SlotDefinition" @@ -2265,7 +2651,9 @@ class SlotDefinition(Definition): disjoint_with: Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]] = empty_list() children_are_mutually_disjoint: Optional[Union[bool, Bool]] = None union_of: Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]] = empty_list() - type_mappings: Optional[Union[Union[str, TypeMappingFramework], list[Union[str, TypeMappingFramework]]]] = empty_list() + type_mappings: Optional[Union[Union[str, TypeMappingFramework], list[Union[str, TypeMappingFramework]]]] = ( + empty_list() + ) is_a: Optional[Union[str, SlotDefinitionName]] = None mixins: Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]] = empty_list() apply_to: Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]] = empty_list() @@ -2294,10 +2682,18 @@ class SlotDefinition(Definition): maximum_cardinality: Optional[int] = None has_member: Optional[Union[dict, AnonymousSlotExpression]] = None all_members: Optional[Union[dict, AnonymousSlotExpression]] = None - none_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = empty_list() - any_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = empty_list() - all_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = empty_list() + none_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]] + ] = empty_list() + any_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, AnonymousSlotExpression], list[Union[dict, AnonymousSlotExpression]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self._is_empty(self.name): @@ -2384,7 +2780,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.transitive_form_of is not None and not isinstance(self.transitive_form_of, SlotDefinitionName): self.transitive_form_of = SlotDefinitionName(self.transitive_form_of) - if self.reflexive_transitive_form_of is not None and not isinstance(self.reflexive_transitive_form_of, SlotDefinitionName): + if self.reflexive_transitive_form_of is not None and not isinstance( + self.reflexive_transitive_form_of, SlotDefinitionName + ): self.reflexive_transitive_form_of = SlotDefinitionName(self.reflexive_transitive_form_of) if self.role is not None and not isinstance(self.role, str): @@ -2410,9 +2808,13 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.disjoint_with, list): self.disjoint_with = [self.disjoint_with] if self.disjoint_with is not None else [] - self.disjoint_with = [v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v) for v in self.disjoint_with] + self.disjoint_with = [ + v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v) for v in self.disjoint_with + ] - if self.children_are_mutually_disjoint is not None and not isinstance(self.children_are_mutually_disjoint, Bool): + if self.children_are_mutually_disjoint is not None and not isinstance( + self.children_are_mutually_disjoint, Bool + ): self.children_are_mutually_disjoint = Bool(self.children_are_mutually_disjoint) if not isinstance(self.union_of, list): @@ -2421,7 +2823,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.type_mappings, list): self.type_mappings = [self.type_mappings] if self.type_mappings is not None else [] - self.type_mappings = [v if isinstance(v, TypeMappingFramework) else TypeMappingFramework(v) for v in self.type_mappings] + self.type_mappings = [ + v if isinstance(v, TypeMappingFramework) else TypeMappingFramework(v) for v in self.type_mappings + ] if self.is_a is not None and not isinstance(self.is_a, SlotDefinitionName): self.is_a = SlotDefinitionName(self.is_a) @@ -2507,19 +2911,28 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.none_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.any_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousSlotExpression) else AnonymousSlotExpression(**as_dict(v)) for v in self.all_of + ] super().__post_init__(**kwargs) @@ -2529,6 +2942,7 @@ class ClassExpression(YAMLRoot): """ A boolean expression that can be used to dynamically determine membership of a class """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["ClassExpression"] @@ -2536,30 +2950,54 @@ class ClassExpression(YAMLRoot): class_name: ClassVar[str] = "class_expression" class_model_uri: ClassVar[URIRef] = LINKML.ClassExpression - any_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - none_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - all_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - slot_conditions: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]] = empty_dict() + any_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]] + ] = empty_list() + none_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = ( + empty_list() + ) + slot_conditions: Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.any_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.none_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.all_of + ] - self._normalize_inlined_as_dict(slot_name="slot_conditions", slot_type=SlotDefinition, key_name="name", keyed=True) + self._normalize_inlined_as_dict( + slot_name="slot_conditions", slot_type=SlotDefinition, key_name="name", keyed=True + ) super().__post_init__(**kwargs) @@ -2574,11 +3012,21 @@ class AnonymousClassExpression(AnonymousExpression): class_model_uri: ClassVar[URIRef] = LINKML.AnonymousClassExpression is_a: Optional[Union[str, DefinitionName]] = None - any_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - none_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - all_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list() - slot_conditions: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]] = empty_dict() + any_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]] + ] = empty_list() + none_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = ( + empty_list() + ) + slot_conditions: Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.is_a is not None and not isinstance(self.is_a, DefinitionName): @@ -2586,21 +3034,35 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.any_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.none_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.all_of + ] - self._normalize_inlined_as_dict(slot_name="slot_conditions", slot_type=SlotDefinition, key_name="name", keyed=True) + self._normalize_inlined_as_dict( + slot_name="slot_conditions", slot_type=SlotDefinition, key_name="name", keyed=True + ) super().__post_init__(**kwargs) @@ -2610,6 +3072,7 @@ class ClassDefinition(Definition): """ an element whose instances are complex objects that may have slot-value assignments """ + _inherited_slots: ClassVar[list[str]] = ["defining_slots", "represents_relationship"] class_class_uri: ClassVar[URIRef] = LINKML["ClassDefinition"] @@ -2619,28 +3082,48 @@ class ClassDefinition(Definition): name: Union[str, ClassDefinitionName] = None slots: Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]] = empty_list() - slot_usage: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]] = empty_dict() - attributes: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]] = empty_dict() + slot_usage: Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ] = empty_dict() + attributes: Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ] = empty_dict() class_uri: Optional[Union[str, URIorCURIE]] = None subclass_of: Optional[Union[str, URIorCURIE]] = None union_of: Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]] = empty_list() defining_slots: Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]] = empty_list() tree_root: Optional[Union[bool, Bool]] = None - unique_keys: Optional[Union[dict[Union[str, UniqueKeyUniqueKeyName], Union[dict, "UniqueKey"]], list[Union[dict, "UniqueKey"]]]] = empty_dict() + unique_keys: Optional[ + Union[dict[Union[str, UniqueKeyUniqueKeyName], Union[dict, "UniqueKey"]], list[Union[dict, "UniqueKey"]]] + ] = empty_dict() rules: Optional[Union[Union[dict, "ClassRule"], list[Union[dict, "ClassRule"]]]] = empty_list() - classification_rules: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = empty_list() + classification_rules: Optional[ + Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]] + ] = empty_list() slot_names_unique: Optional[Union[bool, Bool]] = None represents_relationship: Optional[Union[bool, Bool]] = None - disjoint_with: Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]] = empty_list() + disjoint_with: Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]] = ( + empty_list() + ) children_are_mutually_disjoint: Optional[Union[bool, Bool]] = None is_a: Optional[Union[str, ClassDefinitionName]] = None mixins: Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]] = empty_list() apply_to: Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]] = empty_list() - any_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = empty_list() - exactly_one_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = empty_list() - none_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = empty_list() - all_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = empty_list() - slot_conditions: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]] = empty_dict() + any_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = ( + empty_list() + ) + exactly_one_of: Optional[ + Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]] + ] = empty_list() + none_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = ( + empty_list() + ) + all_of: Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]] = ( + empty_list() + ) + slot_conditions: Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self._is_empty(self.name): @@ -2668,12 +3151,16 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.defining_slots, list): self.defining_slots = [self.defining_slots] if self.defining_slots is not None else [] - self.defining_slots = [v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v) for v in self.defining_slots] + self.defining_slots = [ + v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v) for v in self.defining_slots + ] if self.tree_root is not None and not isinstance(self.tree_root, Bool): self.tree_root = Bool(self.tree_root) - self._normalize_inlined_as_dict(slot_name="unique_keys", slot_type=UniqueKey, key_name="unique_key_name", keyed=True) + self._normalize_inlined_as_dict( + slot_name="unique_keys", slot_type=UniqueKey, key_name="unique_key_name", keyed=True + ) if not isinstance(self.rules, list): self.rules = [self.rules] if self.rules is not None else [] @@ -2681,7 +3168,10 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.classification_rules, list): self.classification_rules = [self.classification_rules] if self.classification_rules is not None else [] - self.classification_rules = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.classification_rules] + self.classification_rules = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.classification_rules + ] if self.slot_names_unique is not None and not isinstance(self.slot_names_unique, Bool): self.slot_names_unique = Bool(self.slot_names_unique) @@ -2691,9 +3181,13 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.disjoint_with, list): self.disjoint_with = [self.disjoint_with] if self.disjoint_with is not None else [] - self.disjoint_with = [v if isinstance(v, ClassDefinitionName) else ClassDefinitionName(v) for v in self.disjoint_with] + self.disjoint_with = [ + v if isinstance(v, ClassDefinitionName) else ClassDefinitionName(v) for v in self.disjoint_with + ] - if self.children_are_mutually_disjoint is not None and not isinstance(self.children_are_mutually_disjoint, Bool): + if self.children_are_mutually_disjoint is not None and not isinstance( + self.children_are_mutually_disjoint, Bool + ): self.children_are_mutually_disjoint = Bool(self.children_are_mutually_disjoint) if self.is_a is not None and not isinstance(self.is_a, ClassDefinitionName): @@ -2709,21 +3203,35 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.any_of, list): self.any_of = [self.any_of] if self.any_of is not None else [] - self.any_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.any_of] + self.any_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.any_of + ] if not isinstance(self.exactly_one_of, list): self.exactly_one_of = [self.exactly_one_of] if self.exactly_one_of is not None else [] - self.exactly_one_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.exactly_one_of] + self.exactly_one_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.exactly_one_of + ] if not isinstance(self.none_of, list): self.none_of = [self.none_of] if self.none_of is not None else [] - self.none_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.none_of] + self.none_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.none_of + ] if not isinstance(self.all_of, list): self.all_of = [self.all_of] if self.all_of is not None else [] - self.all_of = [v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) for v in self.all_of] + self.all_of = [ + v if isinstance(v, AnonymousClassExpression) else AnonymousClassExpression(**as_dict(v)) + for v in self.all_of + ] - self._normalize_inlined_as_dict(slot_name="slot_conditions", slot_type=SlotDefinition, key_name="name", keyed=True) + self._normalize_inlined_as_dict( + slot_name="slot_conditions", slot_type=SlotDefinition, key_name="name", keyed=True + ) super().__post_init__(**kwargs) @@ -2732,6 +3240,7 @@ class ClassLevelRule(YAMLRoot): """ A rule that is applied to classes """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["ClassLevelRule"] @@ -2745,6 +3254,7 @@ class ClassRule(ClassLevelRule): """ A rule that applies to instances of a class """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["ClassRule"] @@ -2759,10 +3269,18 @@ class ClassRule(ClassLevelRule): open_world: Optional[Union[bool, Bool]] = None rank: Optional[int] = None deactivated: Optional[Union[bool, Bool]] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -2823,7 +3341,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -2867,17 +3387,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -2938,6 +3466,7 @@ class ArrayExpression(YAMLRoot): """ defines the dimensions of an array """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["ArrayExpression"] @@ -2948,11 +3477,21 @@ class ArrayExpression(YAMLRoot): exact_number_dimensions: Optional[int] = None minimum_number_dimensions: Optional[int] = None maximum_number_dimensions: Optional[Union[dict, Anything]] = None - dimensions: Optional[Union[Union[dict, "DimensionExpression"], list[Union[dict, "DimensionExpression"]]]] = empty_list() - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + dimensions: Optional[Union[Union[dict, "DimensionExpression"], list[Union[dict, "DimensionExpression"]]]] = ( + empty_list() + ) + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -2994,7 +3533,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.dimensions, list): self.dimensions = [self.dimensions] if self.dimensions is not None else [] - self.dimensions = [v if isinstance(v, DimensionExpression) else DimensionExpression(**as_dict(v)) for v in self.dimensions] + self.dimensions = [ + v if isinstance(v, DimensionExpression) else DimensionExpression(**as_dict(v)) for v in self.dimensions + ] self._normalize_inlined_as_dict(slot_name="extensions", slot_type=Extension, key_name="tag", keyed=True) @@ -3003,7 +3544,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -3047,17 +3590,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -3121,6 +3672,7 @@ class DimensionExpression(YAMLRoot): """ defines one of the dimensions of an array """ + _inherited_slots: ClassVar[list[str]] = ["maximum_cardinality", "minimum_cardinality", "exact_cardinality"] class_class_uri: ClassVar[URIRef] = LINKML["DimensionExpression"] @@ -3132,10 +3684,18 @@ class DimensionExpression(YAMLRoot): maximum_cardinality: Optional[int] = None minimum_cardinality: Optional[int] = None exact_cardinality: Optional[int] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -3188,7 +3748,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -3232,17 +3794,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -3306,6 +3876,7 @@ class PatternExpression(YAMLRoot): """ a regular expression pattern used to evaluate conformance of a string """ + _inherited_slots: ClassVar[list[str]] = ["syntax"] class_class_uri: ClassVar[URIRef] = LINKML["PatternExpression"] @@ -3316,10 +3887,18 @@ class PatternExpression(YAMLRoot): syntax: Optional[str] = None interpolated: Optional[Union[bool, Bool]] = None partial_match: Optional[Union[bool, Bool]] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -3369,7 +3948,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -3413,17 +3994,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -3487,6 +4076,7 @@ class ImportExpression(YAMLRoot): """ an expression describing an import """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["ImportExpression"] @@ -3496,11 +4086,21 @@ class ImportExpression(YAMLRoot): import_from: Union[str, URIorCURIE] = None import_as: Optional[Union[str, NCName]] = None - import_map: Optional[Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]]] = empty_dict() - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + import_map: Optional[ + Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]] + ] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]] = empty_dict() + alt_descriptions: Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -3551,7 +4151,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -3595,17 +4197,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -3669,6 +4279,7 @@ class Setting(YAMLRoot): """ assignment of a key to a value """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Setting"] @@ -3698,6 +4309,7 @@ class Prefix(YAMLRoot): """ prefix URI tuple """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Prefix"] @@ -3727,6 +4339,7 @@ class LocalName(YAMLRoot): """ an attributed label """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["LocalName"] @@ -3756,6 +4369,7 @@ class Example(YAMLRoot): """ usage example and description """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["Example"] @@ -3782,6 +4396,7 @@ class AltDescription(YAMLRoot): """ an attributed description """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["AltDescription"] @@ -3811,6 +4426,7 @@ class PermissibleValue(YAMLRoot): """ a permissible value, accompanied by intended text and an optional mapping to a concept URI """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["PermissibleValue"] @@ -3826,9 +4442,15 @@ class PermissibleValue(YAMLRoot): implements: Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]] = empty_list() is_a: Optional[Union[str, PermissibleValueText]] = None mixins: Optional[Union[Union[str, PermissibleValueText], list[Union[str, PermissibleValueText]]]] = empty_list() - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, AltDescription]], list[Union[dict, AltDescription]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() + alt_descriptions: Optional[ + Union[dict[Union[str, AltDescriptionSource], Union[dict, AltDescription]], list[Union[dict, AltDescription]]] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -3895,7 +4517,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self._normalize_inlined_as_dict(slot_name="annotations", slot_type=Annotation, key_name="tag", keyed=True) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -3939,17 +4563,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -4013,6 +4645,7 @@ class UniqueKey(YAMLRoot): """ a collection of slots whose values uniquely identify an instance of a class """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["UniqueKey"] @@ -4023,10 +4656,16 @@ class UniqueKey(YAMLRoot): unique_key_name: Union[str, UniqueKeyUniqueKeyName] = None unique_key_slots: Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]] = None consider_nulls_inequal: Optional[Union[bool, Bool]] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, AltDescription]], list[Union[dict, AltDescription]]]] = empty_dict() + alt_descriptions: Optional[ + Union[dict[Union[str, AltDescriptionSource], Union[dict, AltDescription]], list[Union[dict, AltDescription]]] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -4069,7 +4708,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.MissingRequiredField("unique_key_slots") if not isinstance(self.unique_key_slots, list): self.unique_key_slots = [self.unique_key_slots] if self.unique_key_slots is not None else [] - self.unique_key_slots = [v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v) for v in self.unique_key_slots] + self.unique_key_slots = [ + v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v) for v in self.unique_key_slots + ] if self.consider_nulls_inequal is not None and not isinstance(self.consider_nulls_inequal, Bool): self.consider_nulls_inequal = Bool(self.consider_nulls_inequal) @@ -4081,7 +4722,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -4125,17 +4768,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -4199,6 +4850,7 @@ class TypeMapping(YAMLRoot): """ Represents how a slot or type can be serialized to a format. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML["TypeMapping"] @@ -4209,10 +4861,16 @@ class TypeMapping(YAMLRoot): framework: Union[str, TypeMappingFramework] = None type: Optional[Union[str, TypeDefinitionName]] = None string_serialization: Optional[str] = None - extensions: Optional[Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]]] = empty_dict() - annotations: Optional[Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]]] = empty_dict() + extensions: Optional[ + Union[dict[Union[str, ExtensionTag], Union[dict, Extension]], list[Union[dict, Extension]]] + ] = empty_dict() + annotations: Optional[ + Union[dict[Union[str, AnnotationTag], Union[dict, Annotation]], list[Union[dict, Annotation]]] + ] = empty_dict() description: Optional[str] = None - alt_descriptions: Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, AltDescription]], list[Union[dict, AltDescription]]]] = empty_dict() + alt_descriptions: Optional[ + Union[dict[Union[str, AltDescriptionSource], Union[dict, AltDescription]], list[Union[dict, AltDescription]]] + ] = empty_dict() title: Optional[str] = None deprecated: Optional[str] = None todos: Optional[Union[str, list[str]]] = empty_list() @@ -4264,7 +4922,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True) + self._normalize_inlined_as_dict( + slot_name="alt_descriptions", slot_type=AltDescription, key_name="source", keyed=True + ) if self.title is not None and not isinstance(self.title, str): self.title = str(self.title) @@ -4308,17 +4968,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] if self.see_also is not None else [] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] self.aliases = [v if isinstance(v, str) else str(v) for v in self.aliases] - self._normalize_inlined_as_dict(slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False) + self._normalize_inlined_as_dict( + slot_name="structured_aliases", slot_type=StructuredAlias, key_name="literal_form", keyed=False + ) if not isinstance(self.mappings, list): self.mappings = [self.mappings] if self.mappings is not None else [] @@ -4382,31 +5050,31 @@ class PvFormulaOptions(EnumDefinitionImpl): """ The formula used to generate the set of permissible values from the code_set values """ + CODE = PermissibleValue( - text="CODE", - description="The permissible values are the set of possible codes in the code set") - CURIE = PermissibleValue( - text="CURIE", - description="The permissible values are the set of CURIES in the code set") - URI = PermissibleValue( - text="URI", - description="The permissible values are the set of code URIs in the code set") + text="CODE", description="The permissible values are the set of possible codes in the code set" + ) + CURIE = PermissibleValue(text="CURIE", description="The permissible values are the set of CURIES in the code set") + URI = PermissibleValue(text="URI", description="The permissible values are the set of code URIs in the code set") FHIR_CODING = PermissibleValue( text="FHIR_CODING", - description="The permissible values are the set of FHIR coding elements derived from the code set") + description="The permissible values are the set of FHIR coding elements derived from the code set", + ) LABEL = PermissibleValue( - text="LABEL", - description="The permissible values are the set of human readable labels in the code set") + text="LABEL", description="The permissible values are the set of human readable labels in the code set" + ) _defn = EnumDefinition( name="PvFormulaOptions", description="The formula used to generate the set of permissible values from the code_set values", ) + class PresenceEnum(EnumDefinitionImpl): """ enumeration of conditions by which a slot value should be set """ + UNCOMMITTED = PermissibleValue(text="UNCOMMITTED") PRESENT = PermissibleValue(text="PRESENT") ABSENT = PermissibleValue(text="ABSENT") @@ -4416,825 +5084,2345 @@ class PresenceEnum(EnumDefinitionImpl): description="enumeration of conditions by which a slot value should be set", ) + class RelationalRoleEnum(EnumDefinitionImpl): """ enumeration of roles a slot on a relationship class can play """ + SUBJECT = PermissibleValue( text="SUBJECT", description="a slot with this role connects a relationship to its subject/source node", - meaning=RDF["subject"]) + meaning=RDF["subject"], + ) OBJECT = PermissibleValue( text="OBJECT", description="a slot with this role connects a relationship to its object/target node", - meaning=RDF["object"]) + meaning=RDF["object"], + ) PREDICATE = PermissibleValue( text="PREDICATE", description="a slot with this role connects a relationship to its predicate/property", - meaning=RDF["predicate"]) + meaning=RDF["predicate"], + ) NODE = PermissibleValue( text="NODE", - description="""a slot with this role connects a symmetric relationship to a node that represents either subject or object node""") + description="""a slot with this role connects a symmetric relationship to a node that represents either subject or object node""", + ) OTHER_ROLE = PermissibleValue( text="OTHER_ROLE", - description="a slot with this role connects a relationship to a node that is not subject/object/predicate") + description="a slot with this role connects a relationship to a node that is not subject/object/predicate", + ) _defn = EnumDefinition( name="RelationalRoleEnum", description="enumeration of roles a slot on a relationship class can play", ) + class AliasPredicateEnum(EnumDefinitionImpl): """ permissible values for the relationship between an element and an alias """ - EXACT_SYNONYM = PermissibleValue( - text="EXACT_SYNONYM", - meaning=SKOS["exactMatch"]) - RELATED_SYNONYM = PermissibleValue( - text="RELATED_SYNONYM", - meaning=SKOS["relatedMatch"]) - BROAD_SYNONYM = PermissibleValue( - text="BROAD_SYNONYM", - meaning=SKOS["broaderMatch"]) - NARROW_SYNONYM = PermissibleValue( - text="NARROW_SYNONYM", - meaning=SKOS["narrowerMatch"]) + + EXACT_SYNONYM = PermissibleValue(text="EXACT_SYNONYM", meaning=SKOS["exactMatch"]) + RELATED_SYNONYM = PermissibleValue(text="RELATED_SYNONYM", meaning=SKOS["relatedMatch"]) + BROAD_SYNONYM = PermissibleValue(text="BROAD_SYNONYM", meaning=SKOS["broaderMatch"]) + NARROW_SYNONYM = PermissibleValue(text="NARROW_SYNONYM", meaning=SKOS["narrowerMatch"]) _defn = EnumDefinition( name="AliasPredicateEnum", description="permissible values for the relationship between an element and an alias", ) + class ObligationLevelEnum(EnumDefinitionImpl): """ The level of obligation or recommendation strength for a metadata element """ + REQUIRED = PermissibleValue( - text="REQUIRED", - description="The metadata element is required to be present in the model") + text="REQUIRED", description="The metadata element is required to be present in the model" + ) RECOMMENDED = PermissibleValue( - text="RECOMMENDED", - description="The metadata element is recommended to be present in the model") + text="RECOMMENDED", description="The metadata element is recommended to be present in the model" + ) OPTIONAL = PermissibleValue( - text="OPTIONAL", - description="The metadata element is optional to be present in the model") - EXAMPLE = PermissibleValue( - text="EXAMPLE", - description="The metadata element is an example of how to use the model") + text="OPTIONAL", description="The metadata element is optional to be present in the model" + ) + EXAMPLE = PermissibleValue(text="EXAMPLE", description="The metadata element is an example of how to use the model") DISCOURAGED = PermissibleValue( - text="DISCOURAGED", - description="The metadata element is allowed but discouraged to be present in the model") + text="DISCOURAGED", description="The metadata element is allowed but discouraged to be present in the model" + ) _defn = EnumDefinition( name="ObligationLevelEnum", description="The level of obligation or recommendation strength for a metadata element", ) + # Slots class slots: pass -slots.name = Slot(uri=RDFS.label, name="name", curie=RDFS.curie('label'), - model_uri=LINKML.name, domain=Element, range=Union[str, ElementName]) - -slots.title = Slot(uri=DCTERMS.title, name="title", curie=DCTERMS.curie('title'), - model_uri=LINKML.title, domain=Element, range=Optional[str]) - -slots.conforms_to = Slot(uri=DCTERMS.conformsTo, name="conforms_to", curie=DCTERMS.curie('conformsTo'), - model_uri=LINKML.conforms_to, domain=Element, range=Optional[str]) - -slots.implements = Slot(uri=LINKML.implements, name="implements", curie=LINKML.curie('implements'), - model_uri=LINKML.implements, domain=Element, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.instantiates = Slot(uri=LINKML.instantiates, name="instantiates", curie=LINKML.curie('instantiates'), - model_uri=LINKML.instantiates, domain=Element, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.categories = Slot(uri=DCTERMS.subject, name="categories", curie=DCTERMS.curie('subject'), - model_uri=LINKML.categories, domain=None, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.keywords = Slot(uri=SCHEMA.keywords, name="keywords", curie=SCHEMA.curie('keywords'), - model_uri=LINKML.keywords, domain=Element, range=Optional[Union[str, list[str]]]) - -slots.definition_uri = Slot(uri=LINKML.definition_uri, name="definition_uri", curie=LINKML.curie('definition_uri'), - model_uri=LINKML.definition_uri, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.id_prefixes = Slot(uri=LINKML.id_prefixes, name="id_prefixes", curie=LINKML.curie('id_prefixes'), - model_uri=LINKML.id_prefixes, domain=Element, range=Optional[Union[Union[str, NCName], list[Union[str, NCName]]]]) - -slots.id_prefixes_are_closed = Slot(uri=LINKML.id_prefixes_are_closed, name="id_prefixes_are_closed", curie=LINKML.curie('id_prefixes_are_closed'), - model_uri=LINKML.id_prefixes_are_closed, domain=Element, range=Optional[Union[bool, Bool]]) - -slots.description = Slot(uri=SKOS.definition, name="description", curie=SKOS.curie('definition'), - model_uri=LINKML.description, domain=Element, range=Optional[str]) - -slots.structured_aliases = Slot(uri=SKOSXL.altLabel, name="structured_aliases", curie=SKOSXL.curie('altLabel'), - model_uri=LINKML.structured_aliases, domain=None, range=Optional[Union[Union[dict, StructuredAlias], list[Union[dict, StructuredAlias]]]]) - -slots.aliases = Slot(uri=SKOS.altLabel, name="aliases", curie=SKOS.curie('altLabel'), - model_uri=LINKML.aliases, domain=Element, range=Optional[Union[str, list[str]]]) - -slots.deprecated = Slot(uri=LINKML.deprecated, name="deprecated", curie=LINKML.curie('deprecated'), - model_uri=LINKML.deprecated, domain=Element, range=Optional[str]) - -slots.todos = Slot(uri=LINKML.todos, name="todos", curie=LINKML.curie('todos'), - model_uri=LINKML.todos, domain=Element, range=Optional[Union[str, list[str]]]) - -slots.notes = Slot(uri=SKOS.editorialNote, name="notes", curie=SKOS.curie('editorialNote'), - model_uri=LINKML.notes, domain=Element, range=Optional[Union[str, list[str]]]) - -slots.comments = Slot(uri=SKOS.note, name="comments", curie=SKOS.curie('note'), - model_uri=LINKML.comments, domain=Element, range=Optional[Union[str, list[str]]]) - -slots.in_subset = Slot(uri=OIO.inSubset, name="in_subset", curie=OIO.curie('inSubset'), - model_uri=LINKML.in_subset, domain=Element, range=Optional[Union[Union[str, SubsetDefinitionName], list[Union[str, SubsetDefinitionName]]]]) - -slots.from_schema = Slot(uri=SKOS.inScheme, name="from_schema", curie=SKOS.curie('inScheme'), - model_uri=LINKML.from_schema, domain=Element, range=Optional[Union[str, URI]]) - -slots.imported_from = Slot(uri=LINKML.imported_from, name="imported_from", curie=LINKML.curie('imported_from'), - model_uri=LINKML.imported_from, domain=Element, range=Optional[str]) - -slots.see_also = Slot(uri=RDFS.seeAlso, name="see_also", curie=RDFS.curie('seeAlso'), - model_uri=LINKML.see_also, domain=Element, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.owned_by = Slot(uri=LINKML.owned_by, name="owned_by", curie=LINKML.curie('owned_by'), - model_uri=LINKML.owned_by, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.created_by = Slot(uri=PAV.createdBy, name="created_by", curie=PAV.curie('createdBy'), - model_uri=LINKML.created_by, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.contributors = Slot(uri=DCTERMS.contributor, name="contributors", curie=DCTERMS.curie('contributor'), - model_uri=LINKML.contributors, domain=Element, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.created_on = Slot(uri=PAV.createdOn, name="created_on", curie=PAV.curie('createdOn'), - model_uri=LINKML.created_on, domain=Element, range=Optional[Union[str, XSDDateTime]]) - -slots.last_updated_on = Slot(uri=PAV.lastUpdatedOn, name="last_updated_on", curie=PAV.curie('lastUpdatedOn'), - model_uri=LINKML.last_updated_on, domain=Element, range=Optional[Union[str, XSDDateTime]]) - -slots.modified_by = Slot(uri=OSLC.modifiedBy, name="modified_by", curie=OSLC.curie('modifiedBy'), - model_uri=LINKML.modified_by, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.status = Slot(uri=BIBO.status, name="status", curie=BIBO.curie('status'), - model_uri=LINKML.status, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.literal_form = Slot(uri=SKOSXL.literalForm, name="literal_form", curie=SKOSXL.curie('literalForm'), - model_uri=LINKML.literal_form, domain=StructuredAlias, range=str) - -slots.alias_predicate = Slot(uri=RDF.predicate, name="alias_predicate", curie=RDF.curie('predicate'), - model_uri=LINKML.alias_predicate, domain=StructuredAlias, range=Optional[Union[str, "AliasPredicateEnum"]]) - -slots.alias_contexts = Slot(uri=LINKML.contexts, name="alias_contexts", curie=LINKML.curie('contexts'), - model_uri=LINKML.alias_contexts, domain=StructuredAlias, range=Optional[Union[Union[str, URI], list[Union[str, URI]]]]) - -slots.in_language = Slot(uri=SCHEMA.inLanguage, name="in_language", curie=SCHEMA.curie('inLanguage'), - model_uri=LINKML.in_language, domain=None, range=Optional[str]) - -slots.source = Slot(uri=DCTERMS.source, name="source", curie=DCTERMS.curie('source'), - model_uri=LINKML.source, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.publisher = Slot(uri=DCTERMS.publisher, name="publisher", curie=DCTERMS.curie('publisher'), - model_uri=LINKML.publisher, domain=Element, range=Optional[Union[str, URIorCURIE]]) - -slots.is_a = Slot(uri=LINKML.is_a, name="is_a", curie=LINKML.curie('is_a'), - model_uri=LINKML.is_a, domain=None, range=Optional[Union[str, DefinitionName]]) - -slots.abstract = Slot(uri=LINKML.abstract, name="abstract", curie=LINKML.curie('abstract'), - model_uri=LINKML.abstract, domain=Definition, range=Optional[Union[bool, Bool]]) - -slots.mixin = Slot(uri=LINKML.mixin, name="mixin", curie=LINKML.curie('mixin'), - model_uri=LINKML.mixin, domain=Definition, range=Optional[Union[bool, Bool]]) - -slots.mixins = Slot(uri=LINKML.mixins, name="mixins", curie=LINKML.curie('mixins'), - model_uri=LINKML.mixins, domain=None, range=Optional[Union[Union[str, DefinitionName], list[Union[str, DefinitionName]]]]) - -slots.apply_to = Slot(uri=LINKML.apply_to, name="apply_to", curie=LINKML.curie('apply_to'), - model_uri=LINKML.apply_to, domain=Definition, range=Optional[Union[Union[str, DefinitionName], list[Union[str, DefinitionName]]]]) - -slots.values_from = Slot(uri=LINKML.values_from, name="values_from", curie=LINKML.curie('values_from'), - model_uri=LINKML.values_from, domain=Definition, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.code_set = Slot(uri=LINKML.code_set, name="code_set", curie=LINKML.curie('code_set'), - model_uri=LINKML.code_set, domain=EnumExpression, range=Optional[Union[str, URIorCURIE]]) - -slots.code_set_version = Slot(uri=LINKML.code_set_version, name="code_set_version", curie=LINKML.curie('code_set_version'), - model_uri=LINKML.code_set_version, domain=EnumExpression, range=Optional[str]) - -slots.code_set_tag = Slot(uri=LINKML.code_set_tag, name="code_set_tag", curie=LINKML.curie('code_set_tag'), - model_uri=LINKML.code_set_tag, domain=EnumExpression, range=Optional[str]) - -slots.pv_formula = Slot(uri=LINKML.pv_formula, name="pv_formula", curie=LINKML.curie('pv_formula'), - model_uri=LINKML.pv_formula, domain=None, range=Optional[Union[str, "PvFormulaOptions"]]) - -slots.permissible_values = Slot(uri=LINKML.permissible_values, name="permissible_values", curie=LINKML.curie('permissible_values'), - model_uri=LINKML.permissible_values, domain=EnumExpression, range=Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]]) - -slots.enum_uri = Slot(uri=LINKML.enum_uri, name="enum_uri", curie=LINKML.curie('enum_uri'), - model_uri=LINKML.enum_uri, domain=EnumDefinition, range=Optional[Union[str, URIorCURIE]]) - -slots.include = Slot(uri=LINKML.include, name="include", curie=LINKML.curie('include'), - model_uri=LINKML.include, domain=EnumExpression, range=Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]]) - -slots.minus = Slot(uri=LINKML.minus, name="minus", curie=LINKML.curie('minus'), - model_uri=LINKML.minus, domain=EnumExpression, range=Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]]) - -slots.inherits = Slot(uri=LINKML.inherits, name="inherits", curie=LINKML.curie('inherits'), - model_uri=LINKML.inherits, domain=EnumExpression, range=Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]]) - -slots.matches = Slot(uri=LINKML.matches, name="matches", curie=LINKML.curie('matches'), - model_uri=LINKML.matches, domain=EnumExpression, range=Optional[Union[dict, "MatchQuery"]]) - -slots.identifier_pattern = Slot(uri=LINKML.identifier_pattern, name="identifier_pattern", curie=LINKML.curie('identifier_pattern'), - model_uri=LINKML.identifier_pattern, domain=MatchQuery, range=Optional[str]) - -slots.concepts = Slot(uri=LINKML.concepts, name="concepts", curie=LINKML.curie('concepts'), - model_uri=LINKML.concepts, domain=EnumExpression, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.reachable_from = Slot(uri=LINKML.reachable_from, name="reachable_from", curie=LINKML.curie('reachable_from'), - model_uri=LINKML.reachable_from, domain=EnumExpression, range=Optional[Union[dict, "ReachabilityQuery"]]) - -slots.source_ontology = Slot(uri=LINKML.source_ontology, name="source_ontology", curie=LINKML.curie('source_ontology'), - model_uri=LINKML.source_ontology, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.is_direct = Slot(uri=LINKML.is_direct, name="is_direct", curie=LINKML.curie('is_direct'), - model_uri=LINKML.is_direct, domain=ReachabilityQuery, range=Optional[Union[bool, Bool]]) - -slots.traverse_up = Slot(uri=LINKML.traverse_up, name="traverse_up", curie=LINKML.curie('traverse_up'), - model_uri=LINKML.traverse_up, domain=ReachabilityQuery, range=Optional[Union[bool, Bool]]) - -slots.include_self = Slot(uri=LINKML.include_self, name="include_self", curie=LINKML.curie('include_self'), - model_uri=LINKML.include_self, domain=ReachabilityQuery, range=Optional[Union[bool, Bool]]) - -slots.relationship_types = Slot(uri=LINKML.relationship_types, name="relationship_types", curie=LINKML.curie('relationship_types'), - model_uri=LINKML.relationship_types, domain=ReachabilityQuery, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.source_nodes = Slot(uri=LINKML.source_nodes, name="source_nodes", curie=LINKML.curie('source_nodes'), - model_uri=LINKML.source_nodes, domain=ReachabilityQuery, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.text = Slot(uri=LINKML.text, name="text", curie=LINKML.curie('text'), - model_uri=LINKML.text, domain=PermissibleValue, range=Union[str, PermissibleValueText]) - -slots.meaning = Slot(uri=LINKML.meaning, name="meaning", curie=LINKML.curie('meaning'), - model_uri=LINKML.meaning, domain=PermissibleValue, range=Optional[Union[str, URIorCURIE]]) - -slots.id = Slot(uri=LINKML.id, name="id", curie=LINKML.curie('id'), - model_uri=LINKML.id, domain=SchemaDefinition, range=Union[str, URI]) - -slots.emit_prefixes = Slot(uri=LINKML.emit_prefixes, name="emit_prefixes", curie=LINKML.curie('emit_prefixes'), - model_uri=LINKML.emit_prefixes, domain=SchemaDefinition, range=Optional[Union[Union[str, NCName], list[Union[str, NCName]]]]) - -slots.version = Slot(uri=PAV.version, name="version", curie=PAV.curie('version'), - model_uri=LINKML.version, domain=SchemaDefinition, range=Optional[str]) - -slots.imports = Slot(uri=LINKML.imports, name="imports", curie=LINKML.curie('imports'), - model_uri=LINKML.imports, domain=SchemaDefinition, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.structured_imports = Slot(uri=LINKML.structured_imports, name="structured_imports", curie=LINKML.curie('structured_imports'), - model_uri=LINKML.structured_imports, domain=SchemaDefinition, range=Optional[Union[Union[dict, "ImportExpression"], list[Union[dict, "ImportExpression"]]]]) - -slots.license = Slot(uri=DCTERMS.license, name="license", curie=DCTERMS.curie('license'), - model_uri=LINKML.license, domain=SchemaDefinition, range=Optional[str]) - -slots.default_curi_maps = Slot(uri=LINKML.default_curi_maps, name="default_curi_maps", curie=LINKML.curie('default_curi_maps'), - model_uri=LINKML.default_curi_maps, domain=SchemaDefinition, range=Optional[Union[str, list[str]]]) - -slots.default_prefix = Slot(uri=LINKML.default_prefix, name="default_prefix", curie=LINKML.curie('default_prefix'), - model_uri=LINKML.default_prefix, domain=SchemaDefinition, range=Optional[str]) - -slots.default_range = Slot(uri=LINKML.default_range, name="default_range", curie=LINKML.curie('default_range'), - model_uri=LINKML.default_range, domain=SchemaDefinition, range=Optional[Union[str, TypeDefinitionName]]) - -slots.subsets = Slot(uri=LINKML.subsets, name="subsets", curie=LINKML.curie('subsets'), - model_uri=LINKML.subsets, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, SubsetDefinitionName], Union[dict, "SubsetDefinition"]], list[Union[dict, "SubsetDefinition"]]]]) - -slots.types = Slot(uri=LINKML.types, name="types", curie=LINKML.curie('types'), - model_uri=LINKML.types, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, TypeDefinitionName], Union[dict, "TypeDefinition"]], list[Union[dict, "TypeDefinition"]]]]) - -slots.enums = Slot(uri=LINKML.enums, name="enums", curie=LINKML.curie('enums'), - model_uri=LINKML.enums, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, EnumDefinitionName], Union[dict, "EnumDefinition"]], list[Union[dict, "EnumDefinition"]]]]) - -slots.slot_definitions = Slot(uri=LINKML.slots, name="slot_definitions", curie=LINKML.curie('slots'), - model_uri=LINKML.slot_definitions, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, "SlotDefinition"]], list[Union[dict, "SlotDefinition"]]]]) - -slots.classes = Slot(uri=LINKML.classes, name="classes", curie=LINKML.curie('classes'), - model_uri=LINKML.classes, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, ClassDefinitionName], Union[dict, "ClassDefinition"]], list[Union[dict, "ClassDefinition"]]]]) - -slots.metamodel_version = Slot(uri=LINKML.metamodel_version, name="metamodel_version", curie=LINKML.curie('metamodel_version'), - model_uri=LINKML.metamodel_version, domain=SchemaDefinition, range=Optional[str]) - -slots.source_file = Slot(uri=LINKML.source_file, name="source_file", curie=LINKML.curie('source_file'), - model_uri=LINKML.source_file, domain=SchemaDefinition, range=Optional[str]) - -slots.source_file_date = Slot(uri=LINKML.source_file_date, name="source_file_date", curie=LINKML.curie('source_file_date'), - model_uri=LINKML.source_file_date, domain=SchemaDefinition, range=Optional[Union[str, XSDDateTime]]) - -slots.source_file_size = Slot(uri=LINKML.source_file_size, name="source_file_size", curie=LINKML.curie('source_file_size'), - model_uri=LINKML.source_file_size, domain=SchemaDefinition, range=Optional[int]) - -slots.generation_date = Slot(uri=LINKML.generation_date, name="generation_date", curie=LINKML.curie('generation_date'), - model_uri=LINKML.generation_date, domain=SchemaDefinition, range=Optional[Union[str, XSDDateTime]]) - -slots.slots = Slot(uri=LINKML.slots, name="slots", curie=LINKML.curie('slots'), - model_uri=LINKML.slots, domain=ClassDefinition, range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]]) - -slots.slot_usage = Slot(uri=LINKML.slot_usage, name="slot_usage", curie=LINKML.curie('slot_usage'), - model_uri=LINKML.slot_usage, domain=ClassDefinition, range=Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]]) - -slots.enum_range = Slot(uri=LINKML.enum_range, name="enum_range", curie=LINKML.curie('enum_range'), - model_uri=LINKML.enum_range, domain=None, range=Optional[Union[dict, EnumExpression]]) - -slots.range_expression = Slot(uri=LINKML.range_expression, name="range_expression", curie=LINKML.curie('range_expression'), - model_uri=LINKML.range_expression, domain=None, range=Optional[Union[dict, "AnonymousClassExpression"]]) - -slots.boolean_slot = Slot(uri=LINKML.boolean_slot, name="boolean_slot", curie=LINKML.curie('boolean_slot'), - model_uri=LINKML.boolean_slot, domain=None, range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]]) - -slots.any_of = Slot(uri=LINKML.any_of, name="any_of", curie=LINKML.curie('any_of'), - model_uri=LINKML.any_of, domain=None, range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]]) - -slots.exactly_one_of = Slot(uri=LINKML.exactly_one_of, name="exactly_one_of", curie=LINKML.curie('exactly_one_of'), - model_uri=LINKML.exactly_one_of, domain=None, range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]]) - -slots.none_of = Slot(uri=LINKML.none_of, name="none_of", curie=LINKML.curie('none_of'), - model_uri=LINKML.none_of, domain=None, range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]]) - -slots.all_of = Slot(uri=LINKML.all_of, name="all_of", curie=LINKML.curie('all_of'), - model_uri=LINKML.all_of, domain=None, range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]]) - -slots.preconditions = Slot(uri=SH.condition, name="preconditions", curie=SH.curie('condition'), - model_uri=LINKML.preconditions, domain=None, range=Optional[Union[dict, AnonymousClassExpression]]) - -slots.postconditions = Slot(uri=LINKML.postconditions, name="postconditions", curie=LINKML.curie('postconditions'), - model_uri=LINKML.postconditions, domain=None, range=Optional[Union[dict, AnonymousClassExpression]]) - -slots.elseconditions = Slot(uri=LINKML.elseconditions, name="elseconditions", curie=LINKML.curie('elseconditions'), - model_uri=LINKML.elseconditions, domain=None, range=Optional[Union[dict, AnonymousClassExpression]]) - -slots.bidirectional = Slot(uri=LINKML.bidirectional, name="bidirectional", curie=LINKML.curie('bidirectional'), - model_uri=LINKML.bidirectional, domain=None, range=Optional[Union[bool, Bool]]) - -slots.open_world = Slot(uri=LINKML.open_world, name="open_world", curie=LINKML.curie('open_world'), - model_uri=LINKML.open_world, domain=None, range=Optional[Union[bool, Bool]]) - -slots.rank = Slot(uri=SH.order, name="rank", curie=SH.curie('order'), - model_uri=LINKML.rank, domain=None, range=Optional[int]) - -slots.deactivated = Slot(uri=SH.deactivated, name="deactivated", curie=SH.curie('deactivated'), - model_uri=LINKML.deactivated, domain=None, range=Optional[Union[bool, Bool]]) - -slots.rules = Slot(uri=SH.rule, name="rules", curie=SH.curie('rule'), - model_uri=LINKML.rules, domain=ClassDefinition, range=Optional[Union[Union[dict, "ClassRule"], list[Union[dict, "ClassRule"]]]]) - -slots.classification_rules = Slot(uri=LINKML.classification_rules, name="classification_rules", curie=LINKML.curie('classification_rules'), - model_uri=LINKML.classification_rules, domain=ClassDefinition, range=Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]]) - -slots.slot_conditions = Slot(uri=LINKML.slot_conditions, name="slot_conditions", curie=LINKML.curie('slot_conditions'), - model_uri=LINKML.slot_conditions, domain=None, range=Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]]) - -slots.attributes = Slot(uri=LINKML.attributes, name="attributes", curie=LINKML.curie('attributes'), - model_uri=LINKML.attributes, domain=ClassDefinition, range=Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]]) - -slots.class_uri = Slot(uri=LINKML.class_uri, name="class_uri", curie=LINKML.curie('class_uri'), - model_uri=LINKML.class_uri, domain=ClassDefinition, range=Optional[Union[str, URIorCURIE]]) - -slots.subclass_of = Slot(uri=LINKML.subclass_of, name="subclass_of", curie=LINKML.curie('subclass_of'), - model_uri=LINKML.subclass_of, domain=ClassDefinition, range=Optional[Union[str, URIorCURIE]]) - -slots.defining_slots = Slot(uri=LINKML.defining_slots, name="defining_slots", curie=LINKML.curie('defining_slots'), - model_uri=LINKML.defining_slots, domain=ClassDefinition, range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]]) - -slots.union_of = Slot(uri=LINKML.union_of, name="union_of", curie=LINKML.curie('union_of'), - model_uri=LINKML.union_of, domain=Element, range=Optional[Union[Union[str, ElementName], list[Union[str, ElementName]]]]) - -slots.tree_root = Slot(uri=LINKML.tree_root, name="tree_root", curie=LINKML.curie('tree_root'), - model_uri=LINKML.tree_root, domain=ClassDefinition, range=Optional[Union[bool, Bool]]) - -slots.unique_keys = Slot(uri=LINKML.unique_keys, name="unique_keys", curie=LINKML.curie('unique_keys'), - model_uri=LINKML.unique_keys, domain=ClassDefinition, range=Optional[Union[dict[Union[str, UniqueKeyUniqueKeyName], Union[dict, "UniqueKey"]], list[Union[dict, "UniqueKey"]]]]) - -slots.unique_key_name = Slot(uri=LINKML.unique_key_name, name="unique_key_name", curie=LINKML.curie('unique_key_name'), - model_uri=LINKML.unique_key_name, domain=UniqueKey, range=Union[str, UniqueKeyUniqueKeyName]) - -slots.consider_nulls_inequal = Slot(uri=LINKML.consider_nulls_inequal, name="consider_nulls_inequal", curie=LINKML.curie('consider_nulls_inequal'), - model_uri=LINKML.consider_nulls_inequal, domain=UniqueKey, range=Optional[Union[bool, Bool]]) - -slots.unique_key_slots = Slot(uri=LINKML.unique_key_slots, name="unique_key_slots", curie=LINKML.curie('unique_key_slots'), - model_uri=LINKML.unique_key_slots, domain=UniqueKey, range=Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]) - -slots.slot_names_unique = Slot(uri=LINKML.slot_names_unique, name="slot_names_unique", curie=LINKML.curie('slot_names_unique'), - model_uri=LINKML.slot_names_unique, domain=Definition, range=Optional[Union[bool, Bool]]) - -slots.domain = Slot(uri=LINKML.domain, name="domain", curie=LINKML.curie('domain'), - model_uri=LINKML.domain, domain=SlotDefinition, range=Optional[Union[str, ClassDefinitionName]]) - -slots.range = Slot(uri=LINKML.range, name="range", curie=LINKML.curie('range'), - model_uri=LINKML.range, domain=SlotDefinition, range=Optional[Union[str, ElementName]]) - -slots.slot_uri = Slot(uri=LINKML.slot_uri, name="slot_uri", curie=LINKML.curie('slot_uri'), - model_uri=LINKML.slot_uri, domain=SlotDefinition, range=Optional[Union[str, URIorCURIE]]) - -slots.multivalued = Slot(uri=LINKML.multivalued, name="multivalued", curie=LINKML.curie('multivalued'), - model_uri=LINKML.multivalued, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.array = Slot(uri=LINKML.array, name="array", curie=LINKML.curie('array'), - model_uri=LINKML.array, domain=SlotDefinition, range=Optional[Union[dict, "ArrayExpression"]]) - -slots.dimensions = Slot(uri=LINKML.dimensions, name="dimensions", curie=LINKML.curie('dimensions'), - model_uri=LINKML.dimensions, domain=ArrayExpression, range=Optional[Union[Union[dict, "DimensionExpression"], list[Union[dict, "DimensionExpression"]]]]) - -slots.minimum_number_dimensions = Slot(uri=LINKML.minimum_number_dimensions, name="minimum_number_dimensions", curie=LINKML.curie('minimum_number_dimensions'), - model_uri=LINKML.minimum_number_dimensions, domain=ArrayExpression, range=Optional[int]) - -slots.maximum_number_dimensions = Slot(uri=LINKML.maximum_number_dimensions, name="maximum_number_dimensions", curie=LINKML.curie('maximum_number_dimensions'), - model_uri=LINKML.maximum_number_dimensions, domain=ArrayExpression, range=Optional[Union[dict, Anything]]) - -slots.exact_number_dimensions = Slot(uri=LINKML.exact_number_dimensions, name="exact_number_dimensions", curie=LINKML.curie('exact_number_dimensions'), - model_uri=LINKML.exact_number_dimensions, domain=ArrayExpression, range=Optional[int]) - -slots.inherited = Slot(uri=LINKML.inherited, name="inherited", curie=LINKML.curie('inherited'), - model_uri=LINKML.inherited, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.readonly = Slot(uri=LINKML.readonly, name="readonly", curie=LINKML.curie('readonly'), - model_uri=LINKML.readonly, domain=SlotDefinition, range=Optional[str]) - -slots.ifabsent = Slot(uri=LINKML.ifabsent, name="ifabsent", curie=LINKML.curie('ifabsent'), - model_uri=LINKML.ifabsent, domain=SlotDefinition, range=Optional[str]) - -slots.implicit_prefix = Slot(uri=LINKML.implicit_prefix, name="implicit_prefix", curie=LINKML.curie('implicit_prefix'), - model_uri=LINKML.implicit_prefix, domain=None, range=Optional[str]) - -slots.value_specification_constant = Slot(uri=LINKML.value_specification_constant, name="value_specification_constant", curie=LINKML.curie('value_specification_constant'), - model_uri=LINKML.value_specification_constant, domain=None, range=Optional[str]) - -slots.list_value_specification_constant = Slot(uri=LINKML.list_value_specification_constant, name="list_value_specification_constant", curie=LINKML.curie('list_value_specification_constant'), - model_uri=LINKML.list_value_specification_constant, domain=None, range=Optional[str]) - -slots.value_presence = Slot(uri=LINKML.value_presence, name="value_presence", curie=LINKML.curie('value_presence'), - model_uri=LINKML.value_presence, domain=SlotDefinition, range=Optional[Union[str, "PresenceEnum"]]) - -slots.equals_string = Slot(uri=LINKML.equals_string, name="equals_string", curie=LINKML.curie('equals_string'), - model_uri=LINKML.equals_string, domain=None, range=Optional[str]) - -slots.equals_number = Slot(uri=LINKML.equals_number, name="equals_number", curie=LINKML.curie('equals_number'), - model_uri=LINKML.equals_number, domain=None, range=Optional[int]) - -slots.equals_expression = Slot(uri=LINKML.equals_expression, name="equals_expression", curie=LINKML.curie('equals_expression'), - model_uri=LINKML.equals_expression, domain=None, range=Optional[str]) - -slots.exact_cardinality = Slot(uri=LINKML.exact_cardinality, name="exact_cardinality", curie=LINKML.curie('exact_cardinality'), - model_uri=LINKML.exact_cardinality, domain=None, range=Optional[int]) - -slots.minimum_cardinality = Slot(uri=LINKML.minimum_cardinality, name="minimum_cardinality", curie=LINKML.curie('minimum_cardinality'), - model_uri=LINKML.minimum_cardinality, domain=None, range=Optional[int]) - -slots.maximum_cardinality = Slot(uri=LINKML.maximum_cardinality, name="maximum_cardinality", curie=LINKML.curie('maximum_cardinality'), - model_uri=LINKML.maximum_cardinality, domain=None, range=Optional[int]) - -slots.equals_string_in = Slot(uri=LINKML.equals_string_in, name="equals_string_in", curie=LINKML.curie('equals_string_in'), - model_uri=LINKML.equals_string_in, domain=None, range=Optional[Union[str, list[str]]]) - -slots.equals_number_in = Slot(uri=LINKML.equals_number_in, name="equals_number_in", curie=LINKML.curie('equals_number_in'), - model_uri=LINKML.equals_number_in, domain=None, range=Optional[Union[int, list[int]]]) - -slots.has_member = Slot(uri=LINKML.has_member, name="has_member", curie=LINKML.curie('has_member'), - model_uri=LINKML.has_member, domain=None, range=Optional[Union[dict, AnonymousSlotExpression]]) - -slots.all_members = Slot(uri=LINKML.all_members, name="all_members", curie=LINKML.curie('all_members'), - model_uri=LINKML.all_members, domain=None, range=Optional[Union[dict, AnonymousSlotExpression]]) - -slots.singular_name = Slot(uri=LINKML.singular_name, name="singular_name", curie=LINKML.curie('singular_name'), - model_uri=LINKML.singular_name, domain=SlotDefinition, range=Optional[str]) - -slots.required = Slot(uri=LINKML.required, name="required", curie=LINKML.curie('required'), - model_uri=LINKML.required, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.recommended = Slot(uri=LINKML.recommended, name="recommended", curie=LINKML.curie('recommended'), - model_uri=LINKML.recommended, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.inapplicable = Slot(uri=LINKML.inapplicable, name="inapplicable", curie=LINKML.curie('inapplicable'), - model_uri=LINKML.inapplicable, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.inlined = Slot(uri=LINKML.inlined, name="inlined", curie=LINKML.curie('inlined'), - model_uri=LINKML.inlined, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.inlined_as_list = Slot(uri=LINKML.inlined_as_list, name="inlined_as_list", curie=LINKML.curie('inlined_as_list'), - model_uri=LINKML.inlined_as_list, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.inlined_as_simple_dict = Slot(uri=LINKML.inlined_as_simple_dict, name="inlined_as_simple_dict", curie=LINKML.curie('inlined_as_simple_dict'), - model_uri=LINKML.inlined_as_simple_dict, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.list_elements_ordered = Slot(uri=LINKML.list_elements_ordered, name="list_elements_ordered", curie=LINKML.curie('list_elements_ordered'), - model_uri=LINKML.list_elements_ordered, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.list_elements_unique = Slot(uri=LINKML.list_elements_unique, name="list_elements_unique", curie=LINKML.curie('list_elements_unique'), - model_uri=LINKML.list_elements_unique, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.shared = Slot(uri=LINKML.shared, name="shared", curie=LINKML.curie('shared'), - model_uri=LINKML.shared, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.key = Slot(uri=LINKML.key, name="key", curie=LINKML.curie('key'), - model_uri=LINKML.key, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.identifier = Slot(uri=LINKML.identifier, name="identifier", curie=LINKML.curie('identifier'), - model_uri=LINKML.identifier, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.designates_type = Slot(uri=LINKML.designates_type, name="designates_type", curie=LINKML.curie('designates_type'), - model_uri=LINKML.designates_type, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.alias = Slot(uri=SKOS.prefLabel, name="alias", curie=SKOS.curie('prefLabel'), - model_uri=LINKML.alias, domain=SlotDefinition, range=Optional[str]) - -slots.owner = Slot(uri=LINKML.owner, name="owner", curie=LINKML.curie('owner'), - model_uri=LINKML.owner, domain=SlotDefinition, range=Optional[Union[str, DefinitionName]]) - -slots.domain_of = Slot(uri=LINKML.domain_of, name="domain_of", curie=LINKML.curie('domain_of'), - model_uri=LINKML.domain_of, domain=SlotDefinition, range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]]) - -slots.is_usage_slot = Slot(uri=LINKML.is_usage_slot, name="is_usage_slot", curie=LINKML.curie('is_usage_slot'), - model_uri=LINKML.is_usage_slot, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.usage_slot_name = Slot(uri=LINKML.usage_slot_name, name="usage_slot_name", curie=LINKML.curie('usage_slot_name'), - model_uri=LINKML.usage_slot_name, domain=SlotDefinition, range=Optional[str]) - -slots.subproperty_of = Slot(uri=RDFS.subPropertyOf, name="subproperty_of", curie=RDFS.curie('subPropertyOf'), - model_uri=LINKML.subproperty_of, domain=SlotDefinition, range=Optional[Union[str, SlotDefinitionName]]) - -slots.disjoint_with = Slot(uri=LINKML.disjoint_with, name="disjoint_with", curie=LINKML.curie('disjoint_with'), - model_uri=LINKML.disjoint_with, domain=Definition, range=Optional[Union[Union[str, DefinitionName], list[Union[str, DefinitionName]]]]) - -slots.children_are_mutually_disjoint = Slot(uri=LINKML.children_are_mutually_disjoint, name="children_are_mutually_disjoint", curie=LINKML.curie('children_are_mutually_disjoint'), - model_uri=LINKML.children_are_mutually_disjoint, domain=Definition, range=Optional[Union[bool, Bool]]) - -slots.relational_logical_characteristic = Slot(uri=LINKML.relational_logical_characteristic, name="relational_logical_characteristic", curie=LINKML.curie('relational_logical_characteristic'), - model_uri=LINKML.relational_logical_characteristic, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.symmetric = Slot(uri=LINKML.symmetric, name="symmetric", curie=LINKML.curie('symmetric'), - model_uri=LINKML.symmetric, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.asymmetric = Slot(uri=LINKML.asymmetric, name="asymmetric", curie=LINKML.curie('asymmetric'), - model_uri=LINKML.asymmetric, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.reflexive = Slot(uri=LINKML.reflexive, name="reflexive", curie=LINKML.curie('reflexive'), - model_uri=LINKML.reflexive, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.irreflexive = Slot(uri=LINKML.irreflexive, name="irreflexive", curie=LINKML.curie('irreflexive'), - model_uri=LINKML.irreflexive, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.locally_reflexive = Slot(uri=LINKML.locally_reflexive, name="locally_reflexive", curie=LINKML.curie('locally_reflexive'), - model_uri=LINKML.locally_reflexive, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.transitive = Slot(uri=LINKML.transitive, name="transitive", curie=LINKML.curie('transitive'), - model_uri=LINKML.transitive, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.transitive_form_of = Slot(uri=LINKML.transitive_form_of, name="transitive_form_of", curie=LINKML.curie('transitive_form_of'), - model_uri=LINKML.transitive_form_of, domain=None, range=Optional[Union[str, SlotDefinitionName]]) - -slots.reflexive_transitive_form_of = Slot(uri=LINKML.reflexive_transitive_form_of, name="reflexive_transitive_form_of", curie=LINKML.curie('reflexive_transitive_form_of'), - model_uri=LINKML.reflexive_transitive_form_of, domain=None, range=Optional[Union[str, SlotDefinitionName]]) - -slots.inverse = Slot(uri=OWL.inverseOf, name="inverse", curie=OWL.curie('inverseOf'), - model_uri=LINKML.inverse, domain=SlotDefinition, range=Optional[Union[str, SlotDefinitionName]]) - -slots.is_class_field = Slot(uri=LINKML.is_class_field, name="is_class_field", curie=LINKML.curie('is_class_field'), - model_uri=LINKML.is_class_field, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.role = Slot(uri=LINKML.role, name="role", curie=LINKML.curie('role'), - model_uri=LINKML.role, domain=SlotDefinition, range=Optional[str]) - -slots.minimum_value = Slot(uri=LINKML.minimum_value, name="minimum_value", curie=LINKML.curie('minimum_value'), - model_uri=LINKML.minimum_value, domain=SlotDefinition, range=Optional[Union[dict, Anything]]) - -slots.maximum_value = Slot(uri=LINKML.maximum_value, name="maximum_value", curie=LINKML.curie('maximum_value'), - model_uri=LINKML.maximum_value, domain=SlotDefinition, range=Optional[Union[dict, Anything]]) - -slots.interpolated = Slot(uri=LINKML.interpolated, name="interpolated", curie=LINKML.curie('interpolated'), - model_uri=LINKML.interpolated, domain=PatternExpression, range=Optional[Union[bool, Bool]]) - -slots.partial_match = Slot(uri=LINKML.partial_match, name="partial_match", curie=LINKML.curie('partial_match'), - model_uri=LINKML.partial_match, domain=PatternExpression, range=Optional[Union[bool, Bool]]) - -slots.pattern = Slot(uri=LINKML.pattern, name="pattern", curie=LINKML.curie('pattern'), - model_uri=LINKML.pattern, domain=Definition, range=Optional[str]) - -slots.syntax = Slot(uri=LINKML.syntax, name="syntax", curie=LINKML.curie('syntax'), - model_uri=LINKML.syntax, domain=PatternExpression, range=Optional[str]) - -slots.structured_pattern = Slot(uri=LINKML.structured_pattern, name="structured_pattern", curie=LINKML.curie('structured_pattern'), - model_uri=LINKML.structured_pattern, domain=Definition, range=Optional[Union[dict, "PatternExpression"]]) - -slots.string_serialization = Slot(uri=LINKML.string_serialization, name="string_serialization", curie=LINKML.curie('string_serialization'), - model_uri=LINKML.string_serialization, domain=Definition, range=Optional[str]) - -slots.bindings = Slot(uri=LINKML.bindings, name="bindings", curie=LINKML.curie('bindings'), - model_uri=LINKML.bindings, domain=Element, range=Optional[Union[Union[dict, "EnumBinding"], list[Union[dict, "EnumBinding"]]]]) - -slots.binds_value_of = Slot(uri=LINKML.binds_value_of, name="binds_value_of", curie=LINKML.curie('binds_value_of'), - model_uri=LINKML.binds_value_of, domain=EnumBinding, range=Optional[str]) - -slots.obligation_level = Slot(uri=LINKML.obligation_level, name="obligation_level", curie=LINKML.curie('obligation_level'), - model_uri=LINKML.obligation_level, domain=None, range=Optional[Union[str, "ObligationLevelEnum"]]) - -slots.type_mappings = Slot(uri=LINKML.type_mappings, name="type_mappings", curie=LINKML.curie('type_mappings'), - model_uri=LINKML.type_mappings, domain=None, range=Optional[Union[Union[str, TypeMappingFramework], list[Union[str, TypeMappingFramework]]]]) - -slots.framework_key = Slot(uri=LINKML.framework, name="framework_key", curie=LINKML.curie('framework'), - model_uri=LINKML.framework_key, domain=None, range=URIRef) - -slots.mapped_type = Slot(uri=LINKML.type, name="mapped_type", curie=LINKML.curie('type'), - model_uri=LINKML.mapped_type, domain=None, range=Optional[Union[str, TypeDefinitionName]]) - -slots.typeof = Slot(uri=LINKML.typeof, name="typeof", curie=LINKML.curie('typeof'), - model_uri=LINKML.typeof, domain=TypeDefinition, range=Optional[Union[str, TypeDefinitionName]]) - -slots.base = Slot(uri=LINKML.base, name="base", curie=LINKML.curie('base'), - model_uri=LINKML.base, domain=TypeDefinition, range=Optional[str]) - -slots.type_uri = Slot(uri=LINKML.uri, name="type_uri", curie=LINKML.curie('uri'), - model_uri=LINKML.type_uri, domain=TypeDefinition, range=Optional[Union[str, URIorCURIE]]) - -slots.repr = Slot(uri=LINKML.repr, name="repr", curie=LINKML.curie('repr'), - model_uri=LINKML.repr, domain=TypeDefinition, range=Optional[str]) - -slots.alt_description_text = Slot(uri=LINKML.description, name="alt_description_text", curie=LINKML.curie('description'), - model_uri=LINKML.alt_description_text, domain=AltDescription, range=str) - -slots.alt_description_source = Slot(uri=LINKML.source, name="alt_description_source", curie=LINKML.curie('source'), - model_uri=LINKML.alt_description_source, domain=AltDescription, range=Union[str, AltDescriptionSource]) - -slots.alt_descriptions = Slot(uri=LINKML.alt_descriptions, name="alt_descriptions", curie=LINKML.curie('alt_descriptions'), - model_uri=LINKML.alt_descriptions, domain=Element, range=Optional[Union[dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]]]]) - -slots.value = Slot(uri=SKOS.example, name="value", curie=SKOS.curie('example'), - model_uri=LINKML.value, domain=Example, range=Optional[str]) - -slots.value_description = Slot(uri=LINKML.description, name="value_description", curie=LINKML.curie('description'), - model_uri=LINKML.value_description, domain=Example, range=Optional[str]) - -slots.value_object = Slot(uri=LINKML.object, name="value_object", curie=LINKML.curie('object'), - model_uri=LINKML.value_object, domain=Example, range=Optional[Union[dict, Anything]]) - -slots.examples = Slot(uri=LINKML.examples, name="examples", curie=LINKML.curie('examples'), - model_uri=LINKML.examples, domain=Element, range=Optional[Union[Union[dict, "Example"], list[Union[dict, "Example"]]]]) - -slots.prefix_prefix = Slot(uri=SH.prefix, name="prefix_prefix", curie=SH.curie('prefix'), - model_uri=LINKML.prefix_prefix, domain=Prefix, range=Union[str, PrefixPrefixPrefix]) - -slots.prefix_reference = Slot(uri=SH.namespace, name="prefix_reference", curie=SH.curie('namespace'), - model_uri=LINKML.prefix_reference, domain=Prefix, range=Union[str, URI]) - -slots.prefixes = Slot(uri=SH.declare, name="prefixes", curie=SH.curie('declare'), - model_uri=LINKML.prefixes, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, PrefixPrefixPrefix], Union[dict, "Prefix"]], list[Union[dict, "Prefix"]]]]) - -slots.setting_key = Slot(uri=LINKML.setting_key, name="setting_key", curie=LINKML.curie('setting_key'), - model_uri=LINKML.setting_key, domain=Setting, range=Union[str, SettingSettingKey]) - -slots.setting_value = Slot(uri=LINKML.setting_value, name="setting_value", curie=LINKML.curie('setting_value'), - model_uri=LINKML.setting_value, domain=Setting, range=str) - -slots.settings = Slot(uri=LINKML.settings, name="settings", curie=LINKML.curie('settings'), - model_uri=LINKML.settings, domain=SchemaDefinition, range=Optional[Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]]]) - -slots.import_from = Slot(uri=LINKML.import_from, name="import_from", curie=LINKML.curie('import_from'), - model_uri=LINKML.import_from, domain=ImportExpression, range=Union[str, URIorCURIE]) - -slots.import_as = Slot(uri=LINKML.import_as, name="import_as", curie=LINKML.curie('import_as'), - model_uri=LINKML.import_as, domain=ImportExpression, range=Optional[Union[str, NCName]]) - -slots.import_map = Slot(uri=LINKML.import_map, name="import_map", curie=LINKML.curie('import_map'), - model_uri=LINKML.import_map, domain=ImportExpression, range=Optional[Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]]]) - -slots.local_name_source = Slot(uri=LINKML.local_name_source, name="local_name_source", curie=LINKML.curie('local_name_source'), - model_uri=LINKML.local_name_source, domain=LocalName, range=Union[str, LocalNameLocalNameSource]) - -slots.local_name_value = Slot(uri=SKOS.altLabel, name="local_name_value", curie=SKOS.curie('altLabel'), - model_uri=LINKML.local_name_value, domain=LocalName, range=str) - -slots.local_names = Slot(uri=LINKML.local_names, name="local_names", curie=LINKML.curie('local_names'), - model_uri=LINKML.local_names, domain=Element, range=Optional[Union[dict[Union[str, LocalNameLocalNameSource], Union[dict, "LocalName"]], list[Union[dict, "LocalName"]]]]) - -slots.slot_group = Slot(uri=SH.group, name="slot_group", curie=SH.curie('group'), - model_uri=LINKML.slot_group, domain=SlotDefinition, range=Optional[Union[str, SlotDefinitionName]]) - -slots.is_grouping_slot = Slot(uri=LINKML.is_grouping_slot, name="is_grouping_slot", curie=LINKML.curie('is_grouping_slot'), - model_uri=LINKML.is_grouping_slot, domain=SlotDefinition, range=Optional[Union[bool, Bool]]) - -slots.followed_by = Slot(uri=LINKML.followed_by, name="followed_by", curie=LINKML.curie('followed_by'), - model_uri=LINKML.followed_by, domain=None, range=Optional[Union[dict, Expression]]) - -slots.reversed = Slot(uri=LINKML.reversed, name="reversed", curie=LINKML.curie('reversed'), - model_uri=LINKML.reversed, domain=None, range=Optional[Union[bool, Bool]]) - -slots.traverse = Slot(uri=LINKML.traverse, name="traverse", curie=LINKML.curie('traverse'), - model_uri=LINKML.traverse, domain=None, range=Optional[Union[str, SlotDefinitionName]]) - -slots.path_rule = Slot(uri=LINKML.path_rule, name="path_rule", curie=LINKML.curie('path_rule'), - model_uri=LINKML.path_rule, domain=SlotDefinition, range=Optional[Union[dict, PathExpression]]) - -slots.represents_relationship = Slot(uri=LINKML.represents_relationship, name="represents_relationship", curie=LINKML.curie('represents_relationship'), - model_uri=LINKML.represents_relationship, domain=ClassDefinition, range=Optional[Union[bool, Bool]]) - -slots.relational_role = Slot(uri=LINKML.relational_role, name="relational_role", curie=LINKML.curie('relational_role'), - model_uri=LINKML.relational_role, domain=SlotDefinition, range=Optional[Union[str, "RelationalRoleEnum"]]) - -slots.schema_definition_name = Slot(uri=RDFS.label, name="schema_definition_name", curie=RDFS.curie('label'), - model_uri=LINKML.schema_definition_name, domain=SchemaDefinition, range=Union[str, SchemaDefinitionName]) - -slots.type_expression_any_of = Slot(uri=LINKML.any_of, name="type_expression_any_of", curie=LINKML.curie('any_of'), - model_uri=LINKML.type_expression_any_of, domain=None, range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]]) - -slots.type_expression_all_of = Slot(uri=LINKML.all_of, name="type_expression_all_of", curie=LINKML.curie('all_of'), - model_uri=LINKML.type_expression_all_of, domain=None, range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]]) - -slots.type_expression_exactly_one_of = Slot(uri=LINKML.exactly_one_of, name="type_expression_exactly_one_of", curie=LINKML.curie('exactly_one_of'), - model_uri=LINKML.type_expression_exactly_one_of, domain=None, range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]]) - -slots.type_expression_none_of = Slot(uri=LINKML.none_of, name="type_expression_none_of", curie=LINKML.curie('none_of'), - model_uri=LINKML.type_expression_none_of, domain=None, range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]]) - -slots.type_definition_union_of = Slot(uri=LINKML.union_of, name="type_definition_union_of", curie=LINKML.curie('union_of'), - model_uri=LINKML.type_definition_union_of, domain=TypeDefinition, range=Optional[Union[Union[str, TypeDefinitionName], list[Union[str, TypeDefinitionName]]]]) - -slots.enum_binding_range = Slot(uri=LINKML.range, name="enum_binding_range", curie=LINKML.curie('range'), - model_uri=LINKML.enum_binding_range, domain=EnumBinding, range=Optional[Union[str, EnumDefinitionName]]) - -slots.structured_alias_categories = Slot(uri=DCTERMS.subject, name="structured_alias_categories", curie=DCTERMS.curie('subject'), - model_uri=LINKML.structured_alias_categories, domain=StructuredAlias, range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]]) - -slots.path_expression_followed_by = Slot(uri=LINKML.followed_by, name="path_expression_followed_by", curie=LINKML.curie('followed_by'), - model_uri=LINKML.path_expression_followed_by, domain=PathExpression, range=Optional[Union[dict, "PathExpression"]]) - -slots.path_expression_any_of = Slot(uri=LINKML.any_of, name="path_expression_any_of", curie=LINKML.curie('any_of'), - model_uri=LINKML.path_expression_any_of, domain=PathExpression, range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]]) - -slots.path_expression_exactly_one_of = Slot(uri=LINKML.exactly_one_of, name="path_expression_exactly_one_of", curie=LINKML.curie('exactly_one_of'), - model_uri=LINKML.path_expression_exactly_one_of, domain=PathExpression, range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]]) - -slots.path_expression_none_of = Slot(uri=LINKML.none_of, name="path_expression_none_of", curie=LINKML.curie('none_of'), - model_uri=LINKML.path_expression_none_of, domain=PathExpression, range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]]) - -slots.path_expression_all_of = Slot(uri=LINKML.all_of, name="path_expression_all_of", curie=LINKML.curie('all_of'), - model_uri=LINKML.path_expression_all_of, domain=PathExpression, range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]]) - -slots.slot_expression_any_of = Slot(uri=LINKML.any_of, name="slot_expression_any_of", curie=LINKML.curie('any_of'), - model_uri=LINKML.slot_expression_any_of, domain=None, range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]]) - -slots.slot_expression_all_of = Slot(uri=LINKML.all_of, name="slot_expression_all_of", curie=LINKML.curie('all_of'), - model_uri=LINKML.slot_expression_all_of, domain=None, range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]]) - -slots.slot_expression_exactly_one_of = Slot(uri=LINKML.exactly_one_of, name="slot_expression_exactly_one_of", curie=LINKML.curie('exactly_one_of'), - model_uri=LINKML.slot_expression_exactly_one_of, domain=None, range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]]) - -slots.slot_expression_none_of = Slot(uri=LINKML.none_of, name="slot_expression_none_of", curie=LINKML.curie('none_of'), - model_uri=LINKML.slot_expression_none_of, domain=None, range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]]) - -slots.slot_definition_is_a = Slot(uri=LINKML.is_a, name="slot_definition_is_a", curie=LINKML.curie('is_a'), - model_uri=LINKML.slot_definition_is_a, domain=SlotDefinition, range=Optional[Union[str, SlotDefinitionName]]) - -slots.slot_definition_mixins = Slot(uri=LINKML.mixins, name="slot_definition_mixins", curie=LINKML.curie('mixins'), - model_uri=LINKML.slot_definition_mixins, domain=SlotDefinition, range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]]) - -slots.slot_definition_apply_to = Slot(uri=LINKML.apply_to, name="slot_definition_apply_to", curie=LINKML.curie('apply_to'), - model_uri=LINKML.slot_definition_apply_to, domain=SlotDefinition, range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]]) - -slots.slot_definition_disjoint_with = Slot(uri=LINKML.disjoint_with, name="slot_definition_disjoint_with", curie=LINKML.curie('disjoint_with'), - model_uri=LINKML.slot_definition_disjoint_with, domain=SlotDefinition, range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]]) - -slots.slot_definition_union_of = Slot(uri=LINKML.union_of, name="slot_definition_union_of", curie=LINKML.curie('union_of'), - model_uri=LINKML.slot_definition_union_of, domain=SlotDefinition, range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]]) - -slots.class_expression_any_of = Slot(uri=LINKML.any_of, name="class_expression_any_of", curie=LINKML.curie('any_of'), - model_uri=LINKML.class_expression_any_of, domain=None, range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]]) - -slots.class_expression_all_of = Slot(uri=LINKML.all_of, name="class_expression_all_of", curie=LINKML.curie('all_of'), - model_uri=LINKML.class_expression_all_of, domain=None, range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]]) - -slots.class_expression_exactly_one_of = Slot(uri=LINKML.exactly_one_of, name="class_expression_exactly_one_of", curie=LINKML.curie('exactly_one_of'), - model_uri=LINKML.class_expression_exactly_one_of, domain=None, range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]]) - -slots.class_expression_none_of = Slot(uri=LINKML.none_of, name="class_expression_none_of", curie=LINKML.curie('none_of'), - model_uri=LINKML.class_expression_none_of, domain=None, range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]]) - -slots.class_definition_is_a = Slot(uri=LINKML.is_a, name="class_definition_is_a", curie=LINKML.curie('is_a'), - model_uri=LINKML.class_definition_is_a, domain=ClassDefinition, range=Optional[Union[str, ClassDefinitionName]]) - -slots.class_definition_mixins = Slot(uri=LINKML.mixins, name="class_definition_mixins", curie=LINKML.curie('mixins'), - model_uri=LINKML.class_definition_mixins, domain=ClassDefinition, range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]]) - -slots.class_definition_apply_to = Slot(uri=LINKML.apply_to, name="class_definition_apply_to", curie=LINKML.curie('apply_to'), - model_uri=LINKML.class_definition_apply_to, domain=ClassDefinition, range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]]) - -slots.class_definition_rules = Slot(uri=SH.rule, name="class_definition_rules", curie=SH.curie('rule'), - model_uri=LINKML.class_definition_rules, domain=ClassDefinition, range=Optional[Union[Union[dict, "ClassRule"], list[Union[dict, "ClassRule"]]]]) - -slots.class_definition_disjoint_with = Slot(uri=LINKML.disjoint_with, name="class_definition_disjoint_with", curie=LINKML.curie('disjoint_with'), - model_uri=LINKML.class_definition_disjoint_with, domain=ClassDefinition, range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]]) - -slots.class_definition_union_of = Slot(uri=LINKML.union_of, name="class_definition_union_of", curie=LINKML.curie('union_of'), - model_uri=LINKML.class_definition_union_of, domain=ClassDefinition, range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]]) - -slots.permissible_value_is_a = Slot(uri=LINKML.is_a, name="permissible_value_is_a", curie=LINKML.curie('is_a'), - model_uri=LINKML.permissible_value_is_a, domain=PermissibleValue, range=Optional[Union[str, PermissibleValueText]]) -slots.permissible_value_mixins = Slot(uri=LINKML.mixins, name="permissible_value_mixins", curie=LINKML.curie('mixins'), - model_uri=LINKML.permissible_value_mixins, domain=PermissibleValue, range=Optional[Union[Union[str, PermissibleValueText], list[Union[str, PermissibleValueText]]]]) +slots.name = Slot( + uri=RDFS.label, + name="name", + curie=RDFS.curie("label"), + model_uri=LINKML.name, + domain=Element, + range=Union[str, ElementName], +) + +slots.title = Slot( + uri=DCTERMS.title, + name="title", + curie=DCTERMS.curie("title"), + model_uri=LINKML.title, + domain=Element, + range=Optional[str], +) + +slots.conforms_to = Slot( + uri=DCTERMS.conformsTo, + name="conforms_to", + curie=DCTERMS.curie("conformsTo"), + model_uri=LINKML.conforms_to, + domain=Element, + range=Optional[str], +) + +slots.implements = Slot( + uri=LINKML.implements, + name="implements", + curie=LINKML.curie("implements"), + model_uri=LINKML.implements, + domain=Element, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.instantiates = Slot( + uri=LINKML.instantiates, + name="instantiates", + curie=LINKML.curie("instantiates"), + model_uri=LINKML.instantiates, + domain=Element, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.categories = Slot( + uri=DCTERMS.subject, + name="categories", + curie=DCTERMS.curie("subject"), + model_uri=LINKML.categories, + domain=None, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.keywords = Slot( + uri=SCHEMA.keywords, + name="keywords", + curie=SCHEMA.curie("keywords"), + model_uri=LINKML.keywords, + domain=Element, + range=Optional[Union[str, list[str]]], +) + +slots.definition_uri = Slot( + uri=LINKML.definition_uri, + name="definition_uri", + curie=LINKML.curie("definition_uri"), + model_uri=LINKML.definition_uri, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.id_prefixes = Slot( + uri=LINKML.id_prefixes, + name="id_prefixes", + curie=LINKML.curie("id_prefixes"), + model_uri=LINKML.id_prefixes, + domain=Element, + range=Optional[Union[Union[str, NCName], list[Union[str, NCName]]]], +) + +slots.id_prefixes_are_closed = Slot( + uri=LINKML.id_prefixes_are_closed, + name="id_prefixes_are_closed", + curie=LINKML.curie("id_prefixes_are_closed"), + model_uri=LINKML.id_prefixes_are_closed, + domain=Element, + range=Optional[Union[bool, Bool]], +) + +slots.description = Slot( + uri=SKOS.definition, + name="description", + curie=SKOS.curie("definition"), + model_uri=LINKML.description, + domain=Element, + range=Optional[str], +) + +slots.structured_aliases = Slot( + uri=SKOSXL.altLabel, + name="structured_aliases", + curie=SKOSXL.curie("altLabel"), + model_uri=LINKML.structured_aliases, + domain=None, + range=Optional[Union[Union[dict, StructuredAlias], list[Union[dict, StructuredAlias]]]], +) + +slots.aliases = Slot( + uri=SKOS.altLabel, + name="aliases", + curie=SKOS.curie("altLabel"), + model_uri=LINKML.aliases, + domain=Element, + range=Optional[Union[str, list[str]]], +) + +slots.deprecated = Slot( + uri=LINKML.deprecated, + name="deprecated", + curie=LINKML.curie("deprecated"), + model_uri=LINKML.deprecated, + domain=Element, + range=Optional[str], +) + +slots.todos = Slot( + uri=LINKML.todos, + name="todos", + curie=LINKML.curie("todos"), + model_uri=LINKML.todos, + domain=Element, + range=Optional[Union[str, list[str]]], +) + +slots.notes = Slot( + uri=SKOS.editorialNote, + name="notes", + curie=SKOS.curie("editorialNote"), + model_uri=LINKML.notes, + domain=Element, + range=Optional[Union[str, list[str]]], +) + +slots.comments = Slot( + uri=SKOS.note, + name="comments", + curie=SKOS.curie("note"), + model_uri=LINKML.comments, + domain=Element, + range=Optional[Union[str, list[str]]], +) + +slots.in_subset = Slot( + uri=OIO.inSubset, + name="in_subset", + curie=OIO.curie("inSubset"), + model_uri=LINKML.in_subset, + domain=Element, + range=Optional[Union[Union[str, SubsetDefinitionName], list[Union[str, SubsetDefinitionName]]]], +) + +slots.from_schema = Slot( + uri=SKOS.inScheme, + name="from_schema", + curie=SKOS.curie("inScheme"), + model_uri=LINKML.from_schema, + domain=Element, + range=Optional[Union[str, URI]], +) + +slots.imported_from = Slot( + uri=LINKML.imported_from, + name="imported_from", + curie=LINKML.curie("imported_from"), + model_uri=LINKML.imported_from, + domain=Element, + range=Optional[str], +) + +slots.see_also = Slot( + uri=RDFS.seeAlso, + name="see_also", + curie=RDFS.curie("seeAlso"), + model_uri=LINKML.see_also, + domain=Element, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.owned_by = Slot( + uri=LINKML.owned_by, + name="owned_by", + curie=LINKML.curie("owned_by"), + model_uri=LINKML.owned_by, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.created_by = Slot( + uri=PAV.createdBy, + name="created_by", + curie=PAV.curie("createdBy"), + model_uri=LINKML.created_by, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.contributors = Slot( + uri=DCTERMS.contributor, + name="contributors", + curie=DCTERMS.curie("contributor"), + model_uri=LINKML.contributors, + domain=Element, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.created_on = Slot( + uri=PAV.createdOn, + name="created_on", + curie=PAV.curie("createdOn"), + model_uri=LINKML.created_on, + domain=Element, + range=Optional[Union[str, XSDDateTime]], +) + +slots.last_updated_on = Slot( + uri=PAV.lastUpdatedOn, + name="last_updated_on", + curie=PAV.curie("lastUpdatedOn"), + model_uri=LINKML.last_updated_on, + domain=Element, + range=Optional[Union[str, XSDDateTime]], +) + +slots.modified_by = Slot( + uri=OSLC.modifiedBy, + name="modified_by", + curie=OSLC.curie("modifiedBy"), + model_uri=LINKML.modified_by, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.status = Slot( + uri=BIBO.status, + name="status", + curie=BIBO.curie("status"), + model_uri=LINKML.status, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.literal_form = Slot( + uri=SKOSXL.literalForm, + name="literal_form", + curie=SKOSXL.curie("literalForm"), + model_uri=LINKML.literal_form, + domain=StructuredAlias, + range=str, +) + +slots.alias_predicate = Slot( + uri=RDF.predicate, + name="alias_predicate", + curie=RDF.curie("predicate"), + model_uri=LINKML.alias_predicate, + domain=StructuredAlias, + range=Optional[Union[str, "AliasPredicateEnum"]], +) + +slots.alias_contexts = Slot( + uri=LINKML.contexts, + name="alias_contexts", + curie=LINKML.curie("contexts"), + model_uri=LINKML.alias_contexts, + domain=StructuredAlias, + range=Optional[Union[Union[str, URI], list[Union[str, URI]]]], +) + +slots.in_language = Slot( + uri=SCHEMA.inLanguage, + name="in_language", + curie=SCHEMA.curie("inLanguage"), + model_uri=LINKML.in_language, + domain=None, + range=Optional[str], +) + +slots.source = Slot( + uri=DCTERMS.source, + name="source", + curie=DCTERMS.curie("source"), + model_uri=LINKML.source, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.publisher = Slot( + uri=DCTERMS.publisher, + name="publisher", + curie=DCTERMS.curie("publisher"), + model_uri=LINKML.publisher, + domain=Element, + range=Optional[Union[str, URIorCURIE]], +) + +slots.is_a = Slot( + uri=LINKML.is_a, + name="is_a", + curie=LINKML.curie("is_a"), + model_uri=LINKML.is_a, + domain=None, + range=Optional[Union[str, DefinitionName]], +) + +slots.abstract = Slot( + uri=LINKML.abstract, + name="abstract", + curie=LINKML.curie("abstract"), + model_uri=LINKML.abstract, + domain=Definition, + range=Optional[Union[bool, Bool]], +) + +slots.mixin = Slot( + uri=LINKML.mixin, + name="mixin", + curie=LINKML.curie("mixin"), + model_uri=LINKML.mixin, + domain=Definition, + range=Optional[Union[bool, Bool]], +) + +slots.mixins = Slot( + uri=LINKML.mixins, + name="mixins", + curie=LINKML.curie("mixins"), + model_uri=LINKML.mixins, + domain=None, + range=Optional[Union[Union[str, DefinitionName], list[Union[str, DefinitionName]]]], +) + +slots.apply_to = Slot( + uri=LINKML.apply_to, + name="apply_to", + curie=LINKML.curie("apply_to"), + model_uri=LINKML.apply_to, + domain=Definition, + range=Optional[Union[Union[str, DefinitionName], list[Union[str, DefinitionName]]]], +) + +slots.values_from = Slot( + uri=LINKML.values_from, + name="values_from", + curie=LINKML.curie("values_from"), + model_uri=LINKML.values_from, + domain=Definition, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.code_set = Slot( + uri=LINKML.code_set, + name="code_set", + curie=LINKML.curie("code_set"), + model_uri=LINKML.code_set, + domain=EnumExpression, + range=Optional[Union[str, URIorCURIE]], +) + +slots.code_set_version = Slot( + uri=LINKML.code_set_version, + name="code_set_version", + curie=LINKML.curie("code_set_version"), + model_uri=LINKML.code_set_version, + domain=EnumExpression, + range=Optional[str], +) + +slots.code_set_tag = Slot( + uri=LINKML.code_set_tag, + name="code_set_tag", + curie=LINKML.curie("code_set_tag"), + model_uri=LINKML.code_set_tag, + domain=EnumExpression, + range=Optional[str], +) + +slots.pv_formula = Slot( + uri=LINKML.pv_formula, + name="pv_formula", + curie=LINKML.curie("pv_formula"), + model_uri=LINKML.pv_formula, + domain=None, + range=Optional[Union[str, "PvFormulaOptions"]], +) + +slots.permissible_values = Slot( + uri=LINKML.permissible_values, + name="permissible_values", + curie=LINKML.curie("permissible_values"), + model_uri=LINKML.permissible_values, + domain=EnumExpression, + range=Optional[ + Union[ + dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], + list[Union[dict, "PermissibleValue"]], + ] + ], +) + +slots.enum_uri = Slot( + uri=LINKML.enum_uri, + name="enum_uri", + curie=LINKML.curie("enum_uri"), + model_uri=LINKML.enum_uri, + domain=EnumDefinition, + range=Optional[Union[str, URIorCURIE]], +) + +slots.include = Slot( + uri=LINKML.include, + name="include", + curie=LINKML.curie("include"), + model_uri=LINKML.include, + domain=EnumExpression, + range=Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]], +) + +slots.minus = Slot( + uri=LINKML.minus, + name="minus", + curie=LINKML.curie("minus"), + model_uri=LINKML.minus, + domain=EnumExpression, + range=Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]], +) + +slots.inherits = Slot( + uri=LINKML.inherits, + name="inherits", + curie=LINKML.curie("inherits"), + model_uri=LINKML.inherits, + domain=EnumExpression, + range=Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]], +) + +slots.matches = Slot( + uri=LINKML.matches, + name="matches", + curie=LINKML.curie("matches"), + model_uri=LINKML.matches, + domain=EnumExpression, + range=Optional[Union[dict, "MatchQuery"]], +) + +slots.identifier_pattern = Slot( + uri=LINKML.identifier_pattern, + name="identifier_pattern", + curie=LINKML.curie("identifier_pattern"), + model_uri=LINKML.identifier_pattern, + domain=MatchQuery, + range=Optional[str], +) + +slots.concepts = Slot( + uri=LINKML.concepts, + name="concepts", + curie=LINKML.curie("concepts"), + model_uri=LINKML.concepts, + domain=EnumExpression, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.reachable_from = Slot( + uri=LINKML.reachable_from, + name="reachable_from", + curie=LINKML.curie("reachable_from"), + model_uri=LINKML.reachable_from, + domain=EnumExpression, + range=Optional[Union[dict, "ReachabilityQuery"]], +) + +slots.source_ontology = Slot( + uri=LINKML.source_ontology, + name="source_ontology", + curie=LINKML.curie("source_ontology"), + model_uri=LINKML.source_ontology, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.is_direct = Slot( + uri=LINKML.is_direct, + name="is_direct", + curie=LINKML.curie("is_direct"), + model_uri=LINKML.is_direct, + domain=ReachabilityQuery, + range=Optional[Union[bool, Bool]], +) + +slots.traverse_up = Slot( + uri=LINKML.traverse_up, + name="traverse_up", + curie=LINKML.curie("traverse_up"), + model_uri=LINKML.traverse_up, + domain=ReachabilityQuery, + range=Optional[Union[bool, Bool]], +) + +slots.include_self = Slot( + uri=LINKML.include_self, + name="include_self", + curie=LINKML.curie("include_self"), + model_uri=LINKML.include_self, + domain=ReachabilityQuery, + range=Optional[Union[bool, Bool]], +) + +slots.relationship_types = Slot( + uri=LINKML.relationship_types, + name="relationship_types", + curie=LINKML.curie("relationship_types"), + model_uri=LINKML.relationship_types, + domain=ReachabilityQuery, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.source_nodes = Slot( + uri=LINKML.source_nodes, + name="source_nodes", + curie=LINKML.curie("source_nodes"), + model_uri=LINKML.source_nodes, + domain=ReachabilityQuery, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.text = Slot( + uri=LINKML.text, + name="text", + curie=LINKML.curie("text"), + model_uri=LINKML.text, + domain=PermissibleValue, + range=Union[str, PermissibleValueText], +) + +slots.meaning = Slot( + uri=LINKML.meaning, + name="meaning", + curie=LINKML.curie("meaning"), + model_uri=LINKML.meaning, + domain=PermissibleValue, + range=Optional[Union[str, URIorCURIE]], +) + +slots.id = Slot( + uri=LINKML.id, + name="id", + curie=LINKML.curie("id"), + model_uri=LINKML.id, + domain=SchemaDefinition, + range=Union[str, URI], +) + +slots.emit_prefixes = Slot( + uri=LINKML.emit_prefixes, + name="emit_prefixes", + curie=LINKML.curie("emit_prefixes"), + model_uri=LINKML.emit_prefixes, + domain=SchemaDefinition, + range=Optional[Union[Union[str, NCName], list[Union[str, NCName]]]], +) + +slots.version = Slot( + uri=PAV.version, + name="version", + curie=PAV.curie("version"), + model_uri=LINKML.version, + domain=SchemaDefinition, + range=Optional[str], +) + +slots.imports = Slot( + uri=LINKML.imports, + name="imports", + curie=LINKML.curie("imports"), + model_uri=LINKML.imports, + domain=SchemaDefinition, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.structured_imports = Slot( + uri=LINKML.structured_imports, + name="structured_imports", + curie=LINKML.curie("structured_imports"), + model_uri=LINKML.structured_imports, + domain=SchemaDefinition, + range=Optional[Union[Union[dict, "ImportExpression"], list[Union[dict, "ImportExpression"]]]], +) + +slots.license = Slot( + uri=DCTERMS.license, + name="license", + curie=DCTERMS.curie("license"), + model_uri=LINKML.license, + domain=SchemaDefinition, + range=Optional[str], +) + +slots.default_curi_maps = Slot( + uri=LINKML.default_curi_maps, + name="default_curi_maps", + curie=LINKML.curie("default_curi_maps"), + model_uri=LINKML.default_curi_maps, + domain=SchemaDefinition, + range=Optional[Union[str, list[str]]], +) + +slots.default_prefix = Slot( + uri=LINKML.default_prefix, + name="default_prefix", + curie=LINKML.curie("default_prefix"), + model_uri=LINKML.default_prefix, + domain=SchemaDefinition, + range=Optional[str], +) + +slots.default_range = Slot( + uri=LINKML.default_range, + name="default_range", + curie=LINKML.curie("default_range"), + model_uri=LINKML.default_range, + domain=SchemaDefinition, + range=Optional[Union[str, TypeDefinitionName]], +) + +slots.subsets = Slot( + uri=LINKML.subsets, + name="subsets", + curie=LINKML.curie("subsets"), + model_uri=LINKML.subsets, + domain=SchemaDefinition, + range=Optional[ + Union[ + dict[Union[str, SubsetDefinitionName], Union[dict, "SubsetDefinition"]], + list[Union[dict, "SubsetDefinition"]], + ] + ], +) + +slots.types = Slot( + uri=LINKML.types, + name="types", + curie=LINKML.curie("types"), + model_uri=LINKML.types, + domain=SchemaDefinition, + range=Optional[ + Union[dict[Union[str, TypeDefinitionName], Union[dict, "TypeDefinition"]], list[Union[dict, "TypeDefinition"]]] + ], +) + +slots.enums = Slot( + uri=LINKML.enums, + name="enums", + curie=LINKML.curie("enums"), + model_uri=LINKML.enums, + domain=SchemaDefinition, + range=Optional[ + Union[dict[Union[str, EnumDefinitionName], Union[dict, "EnumDefinition"]], list[Union[dict, "EnumDefinition"]]] + ], +) + +slots.slot_definitions = Slot( + uri=LINKML.slots, + name="slot_definitions", + curie=LINKML.curie("slots"), + model_uri=LINKML.slot_definitions, + domain=SchemaDefinition, + range=Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, "SlotDefinition"]], list[Union[dict, "SlotDefinition"]]] + ], +) + +slots.classes = Slot( + uri=LINKML.classes, + name="classes", + curie=LINKML.curie("classes"), + model_uri=LINKML.classes, + domain=SchemaDefinition, + range=Optional[ + Union[ + dict[Union[str, ClassDefinitionName], Union[dict, "ClassDefinition"]], list[Union[dict, "ClassDefinition"]] + ] + ], +) + +slots.metamodel_version = Slot( + uri=LINKML.metamodel_version, + name="metamodel_version", + curie=LINKML.curie("metamodel_version"), + model_uri=LINKML.metamodel_version, + domain=SchemaDefinition, + range=Optional[str], +) + +slots.source_file = Slot( + uri=LINKML.source_file, + name="source_file", + curie=LINKML.curie("source_file"), + model_uri=LINKML.source_file, + domain=SchemaDefinition, + range=Optional[str], +) + +slots.source_file_date = Slot( + uri=LINKML.source_file_date, + name="source_file_date", + curie=LINKML.curie("source_file_date"), + model_uri=LINKML.source_file_date, + domain=SchemaDefinition, + range=Optional[Union[str, XSDDateTime]], +) + +slots.source_file_size = Slot( + uri=LINKML.source_file_size, + name="source_file_size", + curie=LINKML.curie("source_file_size"), + model_uri=LINKML.source_file_size, + domain=SchemaDefinition, + range=Optional[int], +) + +slots.generation_date = Slot( + uri=LINKML.generation_date, + name="generation_date", + curie=LINKML.curie("generation_date"), + model_uri=LINKML.generation_date, + domain=SchemaDefinition, + range=Optional[Union[str, XSDDateTime]], +) + +slots.slots = Slot( + uri=LINKML.slots, + name="slots", + curie=LINKML.curie("slots"), + model_uri=LINKML.slots, + domain=ClassDefinition, + range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]], +) + +slots.slot_usage = Slot( + uri=LINKML.slot_usage, + name="slot_usage", + curie=LINKML.curie("slot_usage"), + model_uri=LINKML.slot_usage, + domain=ClassDefinition, + range=Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ], +) + +slots.enum_range = Slot( + uri=LINKML.enum_range, + name="enum_range", + curie=LINKML.curie("enum_range"), + model_uri=LINKML.enum_range, + domain=None, + range=Optional[Union[dict, EnumExpression]], +) + +slots.range_expression = Slot( + uri=LINKML.range_expression, + name="range_expression", + curie=LINKML.curie("range_expression"), + model_uri=LINKML.range_expression, + domain=None, + range=Optional[Union[dict, "AnonymousClassExpression"]], +) + +slots.boolean_slot = Slot( + uri=LINKML.boolean_slot, + name="boolean_slot", + curie=LINKML.curie("boolean_slot"), + model_uri=LINKML.boolean_slot, + domain=None, + range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]], +) + +slots.any_of = Slot( + uri=LINKML.any_of, + name="any_of", + curie=LINKML.curie("any_of"), + model_uri=LINKML.any_of, + domain=None, + range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]], +) + +slots.exactly_one_of = Slot( + uri=LINKML.exactly_one_of, + name="exactly_one_of", + curie=LINKML.curie("exactly_one_of"), + model_uri=LINKML.exactly_one_of, + domain=None, + range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]], +) + +slots.none_of = Slot( + uri=LINKML.none_of, + name="none_of", + curie=LINKML.curie("none_of"), + model_uri=LINKML.none_of, + domain=None, + range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]], +) + +slots.all_of = Slot( + uri=LINKML.all_of, + name="all_of", + curie=LINKML.curie("all_of"), + model_uri=LINKML.all_of, + domain=None, + range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]], +) + +slots.preconditions = Slot( + uri=SH.condition, + name="preconditions", + curie=SH.curie("condition"), + model_uri=LINKML.preconditions, + domain=None, + range=Optional[Union[dict, AnonymousClassExpression]], +) + +slots.postconditions = Slot( + uri=LINKML.postconditions, + name="postconditions", + curie=LINKML.curie("postconditions"), + model_uri=LINKML.postconditions, + domain=None, + range=Optional[Union[dict, AnonymousClassExpression]], +) + +slots.elseconditions = Slot( + uri=LINKML.elseconditions, + name="elseconditions", + curie=LINKML.curie("elseconditions"), + model_uri=LINKML.elseconditions, + domain=None, + range=Optional[Union[dict, AnonymousClassExpression]], +) + +slots.bidirectional = Slot( + uri=LINKML.bidirectional, + name="bidirectional", + curie=LINKML.curie("bidirectional"), + model_uri=LINKML.bidirectional, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.open_world = Slot( + uri=LINKML.open_world, + name="open_world", + curie=LINKML.curie("open_world"), + model_uri=LINKML.open_world, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.rank = Slot( + uri=SH.order, name="rank", curie=SH.curie("order"), model_uri=LINKML.rank, domain=None, range=Optional[int] +) + +slots.deactivated = Slot( + uri=SH.deactivated, + name="deactivated", + curie=SH.curie("deactivated"), + model_uri=LINKML.deactivated, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.rules = Slot( + uri=SH.rule, + name="rules", + curie=SH.curie("rule"), + model_uri=LINKML.rules, + domain=ClassDefinition, + range=Optional[Union[Union[dict, "ClassRule"], list[Union[dict, "ClassRule"]]]], +) + +slots.classification_rules = Slot( + uri=LINKML.classification_rules, + name="classification_rules", + curie=LINKML.curie("classification_rules"), + model_uri=LINKML.classification_rules, + domain=ClassDefinition, + range=Optional[Union[Union[dict, AnonymousClassExpression], list[Union[dict, AnonymousClassExpression]]]], +) + +slots.slot_conditions = Slot( + uri=LINKML.slot_conditions, + name="slot_conditions", + curie=LINKML.curie("slot_conditions"), + model_uri=LINKML.slot_conditions, + domain=None, + range=Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ], +) + +slots.attributes = Slot( + uri=LINKML.attributes, + name="attributes", + curie=LINKML.curie("attributes"), + model_uri=LINKML.attributes, + domain=ClassDefinition, + range=Optional[ + Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]] + ], +) + +slots.class_uri = Slot( + uri=LINKML.class_uri, + name="class_uri", + curie=LINKML.curie("class_uri"), + model_uri=LINKML.class_uri, + domain=ClassDefinition, + range=Optional[Union[str, URIorCURIE]], +) + +slots.subclass_of = Slot( + uri=LINKML.subclass_of, + name="subclass_of", + curie=LINKML.curie("subclass_of"), + model_uri=LINKML.subclass_of, + domain=ClassDefinition, + range=Optional[Union[str, URIorCURIE]], +) + +slots.defining_slots = Slot( + uri=LINKML.defining_slots, + name="defining_slots", + curie=LINKML.curie("defining_slots"), + model_uri=LINKML.defining_slots, + domain=ClassDefinition, + range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]], +) + +slots.union_of = Slot( + uri=LINKML.union_of, + name="union_of", + curie=LINKML.curie("union_of"), + model_uri=LINKML.union_of, + domain=Element, + range=Optional[Union[Union[str, ElementName], list[Union[str, ElementName]]]], +) + +slots.tree_root = Slot( + uri=LINKML.tree_root, + name="tree_root", + curie=LINKML.curie("tree_root"), + model_uri=LINKML.tree_root, + domain=ClassDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.unique_keys = Slot( + uri=LINKML.unique_keys, + name="unique_keys", + curie=LINKML.curie("unique_keys"), + model_uri=LINKML.unique_keys, + domain=ClassDefinition, + range=Optional[ + Union[dict[Union[str, UniqueKeyUniqueKeyName], Union[dict, "UniqueKey"]], list[Union[dict, "UniqueKey"]]] + ], +) + +slots.unique_key_name = Slot( + uri=LINKML.unique_key_name, + name="unique_key_name", + curie=LINKML.curie("unique_key_name"), + model_uri=LINKML.unique_key_name, + domain=UniqueKey, + range=Union[str, UniqueKeyUniqueKeyName], +) + +slots.consider_nulls_inequal = Slot( + uri=LINKML.consider_nulls_inequal, + name="consider_nulls_inequal", + curie=LINKML.curie("consider_nulls_inequal"), + model_uri=LINKML.consider_nulls_inequal, + domain=UniqueKey, + range=Optional[Union[bool, Bool]], +) + +slots.unique_key_slots = Slot( + uri=LINKML.unique_key_slots, + name="unique_key_slots", + curie=LINKML.curie("unique_key_slots"), + model_uri=LINKML.unique_key_slots, + domain=UniqueKey, + range=Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]], +) + +slots.slot_names_unique = Slot( + uri=LINKML.slot_names_unique, + name="slot_names_unique", + curie=LINKML.curie("slot_names_unique"), + model_uri=LINKML.slot_names_unique, + domain=Definition, + range=Optional[Union[bool, Bool]], +) + +slots.domain = Slot( + uri=LINKML.domain, + name="domain", + curie=LINKML.curie("domain"), + model_uri=LINKML.domain, + domain=SlotDefinition, + range=Optional[Union[str, ClassDefinitionName]], +) + +slots.range = Slot( + uri=LINKML.range, + name="range", + curie=LINKML.curie("range"), + model_uri=LINKML.range, + domain=SlotDefinition, + range=Optional[Union[str, ElementName]], +) + +slots.slot_uri = Slot( + uri=LINKML.slot_uri, + name="slot_uri", + curie=LINKML.curie("slot_uri"), + model_uri=LINKML.slot_uri, + domain=SlotDefinition, + range=Optional[Union[str, URIorCURIE]], +) + +slots.multivalued = Slot( + uri=LINKML.multivalued, + name="multivalued", + curie=LINKML.curie("multivalued"), + model_uri=LINKML.multivalued, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.array = Slot( + uri=LINKML.array, + name="array", + curie=LINKML.curie("array"), + model_uri=LINKML.array, + domain=SlotDefinition, + range=Optional[Union[dict, "ArrayExpression"]], +) + +slots.dimensions = Slot( + uri=LINKML.dimensions, + name="dimensions", + curie=LINKML.curie("dimensions"), + model_uri=LINKML.dimensions, + domain=ArrayExpression, + range=Optional[Union[Union[dict, "DimensionExpression"], list[Union[dict, "DimensionExpression"]]]], +) + +slots.minimum_number_dimensions = Slot( + uri=LINKML.minimum_number_dimensions, + name="minimum_number_dimensions", + curie=LINKML.curie("minimum_number_dimensions"), + model_uri=LINKML.minimum_number_dimensions, + domain=ArrayExpression, + range=Optional[int], +) + +slots.maximum_number_dimensions = Slot( + uri=LINKML.maximum_number_dimensions, + name="maximum_number_dimensions", + curie=LINKML.curie("maximum_number_dimensions"), + model_uri=LINKML.maximum_number_dimensions, + domain=ArrayExpression, + range=Optional[Union[dict, Anything]], +) + +slots.exact_number_dimensions = Slot( + uri=LINKML.exact_number_dimensions, + name="exact_number_dimensions", + curie=LINKML.curie("exact_number_dimensions"), + model_uri=LINKML.exact_number_dimensions, + domain=ArrayExpression, + range=Optional[int], +) + +slots.inherited = Slot( + uri=LINKML.inherited, + name="inherited", + curie=LINKML.curie("inherited"), + model_uri=LINKML.inherited, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.readonly = Slot( + uri=LINKML.readonly, + name="readonly", + curie=LINKML.curie("readonly"), + model_uri=LINKML.readonly, + domain=SlotDefinition, + range=Optional[str], +) + +slots.ifabsent = Slot( + uri=LINKML.ifabsent, + name="ifabsent", + curie=LINKML.curie("ifabsent"), + model_uri=LINKML.ifabsent, + domain=SlotDefinition, + range=Optional[str], +) + +slots.implicit_prefix = Slot( + uri=LINKML.implicit_prefix, + name="implicit_prefix", + curie=LINKML.curie("implicit_prefix"), + model_uri=LINKML.implicit_prefix, + domain=None, + range=Optional[str], +) + +slots.value_specification_constant = Slot( + uri=LINKML.value_specification_constant, + name="value_specification_constant", + curie=LINKML.curie("value_specification_constant"), + model_uri=LINKML.value_specification_constant, + domain=None, + range=Optional[str], +) + +slots.list_value_specification_constant = Slot( + uri=LINKML.list_value_specification_constant, + name="list_value_specification_constant", + curie=LINKML.curie("list_value_specification_constant"), + model_uri=LINKML.list_value_specification_constant, + domain=None, + range=Optional[str], +) + +slots.value_presence = Slot( + uri=LINKML.value_presence, + name="value_presence", + curie=LINKML.curie("value_presence"), + model_uri=LINKML.value_presence, + domain=SlotDefinition, + range=Optional[Union[str, "PresenceEnum"]], +) + +slots.equals_string = Slot( + uri=LINKML.equals_string, + name="equals_string", + curie=LINKML.curie("equals_string"), + model_uri=LINKML.equals_string, + domain=None, + range=Optional[str], +) + +slots.equals_number = Slot( + uri=LINKML.equals_number, + name="equals_number", + curie=LINKML.curie("equals_number"), + model_uri=LINKML.equals_number, + domain=None, + range=Optional[int], +) + +slots.equals_expression = Slot( + uri=LINKML.equals_expression, + name="equals_expression", + curie=LINKML.curie("equals_expression"), + model_uri=LINKML.equals_expression, + domain=None, + range=Optional[str], +) + +slots.exact_cardinality = Slot( + uri=LINKML.exact_cardinality, + name="exact_cardinality", + curie=LINKML.curie("exact_cardinality"), + model_uri=LINKML.exact_cardinality, + domain=None, + range=Optional[int], +) + +slots.minimum_cardinality = Slot( + uri=LINKML.minimum_cardinality, + name="minimum_cardinality", + curie=LINKML.curie("minimum_cardinality"), + model_uri=LINKML.minimum_cardinality, + domain=None, + range=Optional[int], +) + +slots.maximum_cardinality = Slot( + uri=LINKML.maximum_cardinality, + name="maximum_cardinality", + curie=LINKML.curie("maximum_cardinality"), + model_uri=LINKML.maximum_cardinality, + domain=None, + range=Optional[int], +) + +slots.equals_string_in = Slot( + uri=LINKML.equals_string_in, + name="equals_string_in", + curie=LINKML.curie("equals_string_in"), + model_uri=LINKML.equals_string_in, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.equals_number_in = Slot( + uri=LINKML.equals_number_in, + name="equals_number_in", + curie=LINKML.curie("equals_number_in"), + model_uri=LINKML.equals_number_in, + domain=None, + range=Optional[Union[int, list[int]]], +) + +slots.has_member = Slot( + uri=LINKML.has_member, + name="has_member", + curie=LINKML.curie("has_member"), + model_uri=LINKML.has_member, + domain=None, + range=Optional[Union[dict, AnonymousSlotExpression]], +) + +slots.all_members = Slot( + uri=LINKML.all_members, + name="all_members", + curie=LINKML.curie("all_members"), + model_uri=LINKML.all_members, + domain=None, + range=Optional[Union[dict, AnonymousSlotExpression]], +) + +slots.singular_name = Slot( + uri=LINKML.singular_name, + name="singular_name", + curie=LINKML.curie("singular_name"), + model_uri=LINKML.singular_name, + domain=SlotDefinition, + range=Optional[str], +) + +slots.required = Slot( + uri=LINKML.required, + name="required", + curie=LINKML.curie("required"), + model_uri=LINKML.required, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.recommended = Slot( + uri=LINKML.recommended, + name="recommended", + curie=LINKML.curie("recommended"), + model_uri=LINKML.recommended, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.inapplicable = Slot( + uri=LINKML.inapplicable, + name="inapplicable", + curie=LINKML.curie("inapplicable"), + model_uri=LINKML.inapplicable, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.inlined = Slot( + uri=LINKML.inlined, + name="inlined", + curie=LINKML.curie("inlined"), + model_uri=LINKML.inlined, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.inlined_as_list = Slot( + uri=LINKML.inlined_as_list, + name="inlined_as_list", + curie=LINKML.curie("inlined_as_list"), + model_uri=LINKML.inlined_as_list, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.inlined_as_simple_dict = Slot( + uri=LINKML.inlined_as_simple_dict, + name="inlined_as_simple_dict", + curie=LINKML.curie("inlined_as_simple_dict"), + model_uri=LINKML.inlined_as_simple_dict, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.list_elements_ordered = Slot( + uri=LINKML.list_elements_ordered, + name="list_elements_ordered", + curie=LINKML.curie("list_elements_ordered"), + model_uri=LINKML.list_elements_ordered, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.list_elements_unique = Slot( + uri=LINKML.list_elements_unique, + name="list_elements_unique", + curie=LINKML.curie("list_elements_unique"), + model_uri=LINKML.list_elements_unique, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.shared = Slot( + uri=LINKML.shared, + name="shared", + curie=LINKML.curie("shared"), + model_uri=LINKML.shared, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.key = Slot( + uri=LINKML.key, + name="key", + curie=LINKML.curie("key"), + model_uri=LINKML.key, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.identifier = Slot( + uri=LINKML.identifier, + name="identifier", + curie=LINKML.curie("identifier"), + model_uri=LINKML.identifier, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.designates_type = Slot( + uri=LINKML.designates_type, + name="designates_type", + curie=LINKML.curie("designates_type"), + model_uri=LINKML.designates_type, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.alias = Slot( + uri=SKOS.prefLabel, + name="alias", + curie=SKOS.curie("prefLabel"), + model_uri=LINKML.alias, + domain=SlotDefinition, + range=Optional[str], +) + +slots.owner = Slot( + uri=LINKML.owner, + name="owner", + curie=LINKML.curie("owner"), + model_uri=LINKML.owner, + domain=SlotDefinition, + range=Optional[Union[str, DefinitionName]], +) + +slots.domain_of = Slot( + uri=LINKML.domain_of, + name="domain_of", + curie=LINKML.curie("domain_of"), + model_uri=LINKML.domain_of, + domain=SlotDefinition, + range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]], +) + +slots.is_usage_slot = Slot( + uri=LINKML.is_usage_slot, + name="is_usage_slot", + curie=LINKML.curie("is_usage_slot"), + model_uri=LINKML.is_usage_slot, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.usage_slot_name = Slot( + uri=LINKML.usage_slot_name, + name="usage_slot_name", + curie=LINKML.curie("usage_slot_name"), + model_uri=LINKML.usage_slot_name, + domain=SlotDefinition, + range=Optional[str], +) + +slots.subproperty_of = Slot( + uri=RDFS.subPropertyOf, + name="subproperty_of", + curie=RDFS.curie("subPropertyOf"), + model_uri=LINKML.subproperty_of, + domain=SlotDefinition, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.disjoint_with = Slot( + uri=LINKML.disjoint_with, + name="disjoint_with", + curie=LINKML.curie("disjoint_with"), + model_uri=LINKML.disjoint_with, + domain=Definition, + range=Optional[Union[Union[str, DefinitionName], list[Union[str, DefinitionName]]]], +) + +slots.children_are_mutually_disjoint = Slot( + uri=LINKML.children_are_mutually_disjoint, + name="children_are_mutually_disjoint", + curie=LINKML.curie("children_are_mutually_disjoint"), + model_uri=LINKML.children_are_mutually_disjoint, + domain=Definition, + range=Optional[Union[bool, Bool]], +) + +slots.relational_logical_characteristic = Slot( + uri=LINKML.relational_logical_characteristic, + name="relational_logical_characteristic", + curie=LINKML.curie("relational_logical_characteristic"), + model_uri=LINKML.relational_logical_characteristic, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.symmetric = Slot( + uri=LINKML.symmetric, + name="symmetric", + curie=LINKML.curie("symmetric"), + model_uri=LINKML.symmetric, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.asymmetric = Slot( + uri=LINKML.asymmetric, + name="asymmetric", + curie=LINKML.curie("asymmetric"), + model_uri=LINKML.asymmetric, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.reflexive = Slot( + uri=LINKML.reflexive, + name="reflexive", + curie=LINKML.curie("reflexive"), + model_uri=LINKML.reflexive, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.irreflexive = Slot( + uri=LINKML.irreflexive, + name="irreflexive", + curie=LINKML.curie("irreflexive"), + model_uri=LINKML.irreflexive, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.locally_reflexive = Slot( + uri=LINKML.locally_reflexive, + name="locally_reflexive", + curie=LINKML.curie("locally_reflexive"), + model_uri=LINKML.locally_reflexive, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.transitive = Slot( + uri=LINKML.transitive, + name="transitive", + curie=LINKML.curie("transitive"), + model_uri=LINKML.transitive, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.transitive_form_of = Slot( + uri=LINKML.transitive_form_of, + name="transitive_form_of", + curie=LINKML.curie("transitive_form_of"), + model_uri=LINKML.transitive_form_of, + domain=None, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.reflexive_transitive_form_of = Slot( + uri=LINKML.reflexive_transitive_form_of, + name="reflexive_transitive_form_of", + curie=LINKML.curie("reflexive_transitive_form_of"), + model_uri=LINKML.reflexive_transitive_form_of, + domain=None, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.inverse = Slot( + uri=OWL.inverseOf, + name="inverse", + curie=OWL.curie("inverseOf"), + model_uri=LINKML.inverse, + domain=SlotDefinition, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.is_class_field = Slot( + uri=LINKML.is_class_field, + name="is_class_field", + curie=LINKML.curie("is_class_field"), + model_uri=LINKML.is_class_field, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.role = Slot( + uri=LINKML.role, + name="role", + curie=LINKML.curie("role"), + model_uri=LINKML.role, + domain=SlotDefinition, + range=Optional[str], +) + +slots.minimum_value = Slot( + uri=LINKML.minimum_value, + name="minimum_value", + curie=LINKML.curie("minimum_value"), + model_uri=LINKML.minimum_value, + domain=SlotDefinition, + range=Optional[Union[dict, Anything]], +) + +slots.maximum_value = Slot( + uri=LINKML.maximum_value, + name="maximum_value", + curie=LINKML.curie("maximum_value"), + model_uri=LINKML.maximum_value, + domain=SlotDefinition, + range=Optional[Union[dict, Anything]], +) + +slots.interpolated = Slot( + uri=LINKML.interpolated, + name="interpolated", + curie=LINKML.curie("interpolated"), + model_uri=LINKML.interpolated, + domain=PatternExpression, + range=Optional[Union[bool, Bool]], +) + +slots.partial_match = Slot( + uri=LINKML.partial_match, + name="partial_match", + curie=LINKML.curie("partial_match"), + model_uri=LINKML.partial_match, + domain=PatternExpression, + range=Optional[Union[bool, Bool]], +) + +slots.pattern = Slot( + uri=LINKML.pattern, + name="pattern", + curie=LINKML.curie("pattern"), + model_uri=LINKML.pattern, + domain=Definition, + range=Optional[str], +) + +slots.syntax = Slot( + uri=LINKML.syntax, + name="syntax", + curie=LINKML.curie("syntax"), + model_uri=LINKML.syntax, + domain=PatternExpression, + range=Optional[str], +) + +slots.structured_pattern = Slot( + uri=LINKML.structured_pattern, + name="structured_pattern", + curie=LINKML.curie("structured_pattern"), + model_uri=LINKML.structured_pattern, + domain=Definition, + range=Optional[Union[dict, "PatternExpression"]], +) + +slots.string_serialization = Slot( + uri=LINKML.string_serialization, + name="string_serialization", + curie=LINKML.curie("string_serialization"), + model_uri=LINKML.string_serialization, + domain=Definition, + range=Optional[str], +) + +slots.bindings = Slot( + uri=LINKML.bindings, + name="bindings", + curie=LINKML.curie("bindings"), + model_uri=LINKML.bindings, + domain=Element, + range=Optional[Union[Union[dict, "EnumBinding"], list[Union[dict, "EnumBinding"]]]], +) + +slots.binds_value_of = Slot( + uri=LINKML.binds_value_of, + name="binds_value_of", + curie=LINKML.curie("binds_value_of"), + model_uri=LINKML.binds_value_of, + domain=EnumBinding, + range=Optional[str], +) + +slots.obligation_level = Slot( + uri=LINKML.obligation_level, + name="obligation_level", + curie=LINKML.curie("obligation_level"), + model_uri=LINKML.obligation_level, + domain=None, + range=Optional[Union[str, "ObligationLevelEnum"]], +) + +slots.type_mappings = Slot( + uri=LINKML.type_mappings, + name="type_mappings", + curie=LINKML.curie("type_mappings"), + model_uri=LINKML.type_mappings, + domain=None, + range=Optional[Union[Union[str, TypeMappingFramework], list[Union[str, TypeMappingFramework]]]], +) + +slots.framework_key = Slot( + uri=LINKML.framework, + name="framework_key", + curie=LINKML.curie("framework"), + model_uri=LINKML.framework_key, + domain=None, + range=URIRef, +) + +slots.mapped_type = Slot( + uri=LINKML.type, + name="mapped_type", + curie=LINKML.curie("type"), + model_uri=LINKML.mapped_type, + domain=None, + range=Optional[Union[str, TypeDefinitionName]], +) + +slots.typeof = Slot( + uri=LINKML.typeof, + name="typeof", + curie=LINKML.curie("typeof"), + model_uri=LINKML.typeof, + domain=TypeDefinition, + range=Optional[Union[str, TypeDefinitionName]], +) + +slots.base = Slot( + uri=LINKML.base, + name="base", + curie=LINKML.curie("base"), + model_uri=LINKML.base, + domain=TypeDefinition, + range=Optional[str], +) + +slots.type_uri = Slot( + uri=LINKML.uri, + name="type_uri", + curie=LINKML.curie("uri"), + model_uri=LINKML.type_uri, + domain=TypeDefinition, + range=Optional[Union[str, URIorCURIE]], +) + +slots.repr = Slot( + uri=LINKML.repr, + name="repr", + curie=LINKML.curie("repr"), + model_uri=LINKML.repr, + domain=TypeDefinition, + range=Optional[str], +) + +slots.alt_description_text = Slot( + uri=LINKML.description, + name="alt_description_text", + curie=LINKML.curie("description"), + model_uri=LINKML.alt_description_text, + domain=AltDescription, + range=str, +) + +slots.alt_description_source = Slot( + uri=LINKML.source, + name="alt_description_source", + curie=LINKML.curie("source"), + model_uri=LINKML.alt_description_source, + domain=AltDescription, + range=Union[str, AltDescriptionSource], +) + +slots.alt_descriptions = Slot( + uri=LINKML.alt_descriptions, + name="alt_descriptions", + curie=LINKML.curie("alt_descriptions"), + model_uri=LINKML.alt_descriptions, + domain=Element, + range=Optional[ + Union[ + dict[Union[str, AltDescriptionSource], Union[dict, "AltDescription"]], list[Union[dict, "AltDescription"]] + ] + ], +) + +slots.value = Slot( + uri=SKOS.example, + name="value", + curie=SKOS.curie("example"), + model_uri=LINKML.value, + domain=Example, + range=Optional[str], +) + +slots.value_description = Slot( + uri=LINKML.description, + name="value_description", + curie=LINKML.curie("description"), + model_uri=LINKML.value_description, + domain=Example, + range=Optional[str], +) + +slots.value_object = Slot( + uri=LINKML.object, + name="value_object", + curie=LINKML.curie("object"), + model_uri=LINKML.value_object, + domain=Example, + range=Optional[Union[dict, Anything]], +) + +slots.examples = Slot( + uri=LINKML.examples, + name="examples", + curie=LINKML.curie("examples"), + model_uri=LINKML.examples, + domain=Element, + range=Optional[Union[Union[dict, "Example"], list[Union[dict, "Example"]]]], +) + +slots.prefix_prefix = Slot( + uri=SH.prefix, + name="prefix_prefix", + curie=SH.curie("prefix"), + model_uri=LINKML.prefix_prefix, + domain=Prefix, + range=Union[str, PrefixPrefixPrefix], +) + +slots.prefix_reference = Slot( + uri=SH.namespace, + name="prefix_reference", + curie=SH.curie("namespace"), + model_uri=LINKML.prefix_reference, + domain=Prefix, + range=Union[str, URI], +) + +slots.prefixes = Slot( + uri=SH.declare, + name="prefixes", + curie=SH.curie("declare"), + model_uri=LINKML.prefixes, + domain=SchemaDefinition, + range=Optional[Union[dict[Union[str, PrefixPrefixPrefix], Union[dict, "Prefix"]], list[Union[dict, "Prefix"]]]], +) + +slots.setting_key = Slot( + uri=LINKML.setting_key, + name="setting_key", + curie=LINKML.curie("setting_key"), + model_uri=LINKML.setting_key, + domain=Setting, + range=Union[str, SettingSettingKey], +) + +slots.setting_value = Slot( + uri=LINKML.setting_value, + name="setting_value", + curie=LINKML.curie("setting_value"), + model_uri=LINKML.setting_value, + domain=Setting, + range=str, +) + +slots.settings = Slot( + uri=LINKML.settings, + name="settings", + curie=LINKML.curie("settings"), + model_uri=LINKML.settings, + domain=SchemaDefinition, + range=Optional[Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]]], +) + +slots.import_from = Slot( + uri=LINKML.import_from, + name="import_from", + curie=LINKML.curie("import_from"), + model_uri=LINKML.import_from, + domain=ImportExpression, + range=Union[str, URIorCURIE], +) + +slots.import_as = Slot( + uri=LINKML.import_as, + name="import_as", + curie=LINKML.curie("import_as"), + model_uri=LINKML.import_as, + domain=ImportExpression, + range=Optional[Union[str, NCName]], +) + +slots.import_map = Slot( + uri=LINKML.import_map, + name="import_map", + curie=LINKML.curie("import_map"), + model_uri=LINKML.import_map, + domain=ImportExpression, + range=Optional[Union[dict[Union[str, SettingSettingKey], Union[dict, "Setting"]], list[Union[dict, "Setting"]]]], +) + +slots.local_name_source = Slot( + uri=LINKML.local_name_source, + name="local_name_source", + curie=LINKML.curie("local_name_source"), + model_uri=LINKML.local_name_source, + domain=LocalName, + range=Union[str, LocalNameLocalNameSource], +) + +slots.local_name_value = Slot( + uri=SKOS.altLabel, + name="local_name_value", + curie=SKOS.curie("altLabel"), + model_uri=LINKML.local_name_value, + domain=LocalName, + range=str, +) + +slots.local_names = Slot( + uri=LINKML.local_names, + name="local_names", + curie=LINKML.curie("local_names"), + model_uri=LINKML.local_names, + domain=Element, + range=Optional[ + Union[dict[Union[str, LocalNameLocalNameSource], Union[dict, "LocalName"]], list[Union[dict, "LocalName"]]] + ], +) + +slots.slot_group = Slot( + uri=SH.group, + name="slot_group", + curie=SH.curie("group"), + model_uri=LINKML.slot_group, + domain=SlotDefinition, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.is_grouping_slot = Slot( + uri=LINKML.is_grouping_slot, + name="is_grouping_slot", + curie=LINKML.curie("is_grouping_slot"), + model_uri=LINKML.is_grouping_slot, + domain=SlotDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.followed_by = Slot( + uri=LINKML.followed_by, + name="followed_by", + curie=LINKML.curie("followed_by"), + model_uri=LINKML.followed_by, + domain=None, + range=Optional[Union[dict, Expression]], +) + +slots.reversed = Slot( + uri=LINKML.reversed, + name="reversed", + curie=LINKML.curie("reversed"), + model_uri=LINKML.reversed, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.traverse = Slot( + uri=LINKML.traverse, + name="traverse", + curie=LINKML.curie("traverse"), + model_uri=LINKML.traverse, + domain=None, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.path_rule = Slot( + uri=LINKML.path_rule, + name="path_rule", + curie=LINKML.curie("path_rule"), + model_uri=LINKML.path_rule, + domain=SlotDefinition, + range=Optional[Union[dict, PathExpression]], +) + +slots.represents_relationship = Slot( + uri=LINKML.represents_relationship, + name="represents_relationship", + curie=LINKML.curie("represents_relationship"), + model_uri=LINKML.represents_relationship, + domain=ClassDefinition, + range=Optional[Union[bool, Bool]], +) + +slots.relational_role = Slot( + uri=LINKML.relational_role, + name="relational_role", + curie=LINKML.curie("relational_role"), + model_uri=LINKML.relational_role, + domain=SlotDefinition, + range=Optional[Union[str, "RelationalRoleEnum"]], +) + +slots.schema_definition_name = Slot( + uri=RDFS.label, + name="schema_definition_name", + curie=RDFS.curie("label"), + model_uri=LINKML.schema_definition_name, + domain=SchemaDefinition, + range=Union[str, SchemaDefinitionName], +) + +slots.type_expression_any_of = Slot( + uri=LINKML.any_of, + name="type_expression_any_of", + curie=LINKML.curie("any_of"), + model_uri=LINKML.type_expression_any_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]], +) + +slots.type_expression_all_of = Slot( + uri=LINKML.all_of, + name="type_expression_all_of", + curie=LINKML.curie("all_of"), + model_uri=LINKML.type_expression_all_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]], +) + +slots.type_expression_exactly_one_of = Slot( + uri=LINKML.exactly_one_of, + name="type_expression_exactly_one_of", + curie=LINKML.curie("exactly_one_of"), + model_uri=LINKML.type_expression_exactly_one_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]], +) + +slots.type_expression_none_of = Slot( + uri=LINKML.none_of, + name="type_expression_none_of", + curie=LINKML.curie("none_of"), + model_uri=LINKML.type_expression_none_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousTypeExpression"], list[Union[dict, "AnonymousTypeExpression"]]]], +) + +slots.type_definition_union_of = Slot( + uri=LINKML.union_of, + name="type_definition_union_of", + curie=LINKML.curie("union_of"), + model_uri=LINKML.type_definition_union_of, + domain=TypeDefinition, + range=Optional[Union[Union[str, TypeDefinitionName], list[Union[str, TypeDefinitionName]]]], +) + +slots.enum_binding_range = Slot( + uri=LINKML.range, + name="enum_binding_range", + curie=LINKML.curie("range"), + model_uri=LINKML.enum_binding_range, + domain=EnumBinding, + range=Optional[Union[str, EnumDefinitionName]], +) + +slots.structured_alias_categories = Slot( + uri=DCTERMS.subject, + name="structured_alias_categories", + curie=DCTERMS.curie("subject"), + model_uri=LINKML.structured_alias_categories, + domain=StructuredAlias, + range=Optional[Union[Union[str, URIorCURIE], list[Union[str, URIorCURIE]]]], +) + +slots.path_expression_followed_by = Slot( + uri=LINKML.followed_by, + name="path_expression_followed_by", + curie=LINKML.curie("followed_by"), + model_uri=LINKML.path_expression_followed_by, + domain=PathExpression, + range=Optional[Union[dict, "PathExpression"]], +) + +slots.path_expression_any_of = Slot( + uri=LINKML.any_of, + name="path_expression_any_of", + curie=LINKML.curie("any_of"), + model_uri=LINKML.path_expression_any_of, + domain=PathExpression, + range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]], +) + +slots.path_expression_exactly_one_of = Slot( + uri=LINKML.exactly_one_of, + name="path_expression_exactly_one_of", + curie=LINKML.curie("exactly_one_of"), + model_uri=LINKML.path_expression_exactly_one_of, + domain=PathExpression, + range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]], +) + +slots.path_expression_none_of = Slot( + uri=LINKML.none_of, + name="path_expression_none_of", + curie=LINKML.curie("none_of"), + model_uri=LINKML.path_expression_none_of, + domain=PathExpression, + range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]], +) + +slots.path_expression_all_of = Slot( + uri=LINKML.all_of, + name="path_expression_all_of", + curie=LINKML.curie("all_of"), + model_uri=LINKML.path_expression_all_of, + domain=PathExpression, + range=Optional[Union[Union[dict, "PathExpression"], list[Union[dict, "PathExpression"]]]], +) + +slots.slot_expression_any_of = Slot( + uri=LINKML.any_of, + name="slot_expression_any_of", + curie=LINKML.curie("any_of"), + model_uri=LINKML.slot_expression_any_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]], +) + +slots.slot_expression_all_of = Slot( + uri=LINKML.all_of, + name="slot_expression_all_of", + curie=LINKML.curie("all_of"), + model_uri=LINKML.slot_expression_all_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]], +) + +slots.slot_expression_exactly_one_of = Slot( + uri=LINKML.exactly_one_of, + name="slot_expression_exactly_one_of", + curie=LINKML.curie("exactly_one_of"), + model_uri=LINKML.slot_expression_exactly_one_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]], +) + +slots.slot_expression_none_of = Slot( + uri=LINKML.none_of, + name="slot_expression_none_of", + curie=LINKML.curie("none_of"), + model_uri=LINKML.slot_expression_none_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousSlotExpression"], list[Union[dict, "AnonymousSlotExpression"]]]], +) + +slots.slot_definition_is_a = Slot( + uri=LINKML.is_a, + name="slot_definition_is_a", + curie=LINKML.curie("is_a"), + model_uri=LINKML.slot_definition_is_a, + domain=SlotDefinition, + range=Optional[Union[str, SlotDefinitionName]], +) + +slots.slot_definition_mixins = Slot( + uri=LINKML.mixins, + name="slot_definition_mixins", + curie=LINKML.curie("mixins"), + model_uri=LINKML.slot_definition_mixins, + domain=SlotDefinition, + range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]], +) + +slots.slot_definition_apply_to = Slot( + uri=LINKML.apply_to, + name="slot_definition_apply_to", + curie=LINKML.curie("apply_to"), + model_uri=LINKML.slot_definition_apply_to, + domain=SlotDefinition, + range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]], +) + +slots.slot_definition_disjoint_with = Slot( + uri=LINKML.disjoint_with, + name="slot_definition_disjoint_with", + curie=LINKML.curie("disjoint_with"), + model_uri=LINKML.slot_definition_disjoint_with, + domain=SlotDefinition, + range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]], +) + +slots.slot_definition_union_of = Slot( + uri=LINKML.union_of, + name="slot_definition_union_of", + curie=LINKML.curie("union_of"), + model_uri=LINKML.slot_definition_union_of, + domain=SlotDefinition, + range=Optional[Union[Union[str, SlotDefinitionName], list[Union[str, SlotDefinitionName]]]], +) + +slots.class_expression_any_of = Slot( + uri=LINKML.any_of, + name="class_expression_any_of", + curie=LINKML.curie("any_of"), + model_uri=LINKML.class_expression_any_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]], +) + +slots.class_expression_all_of = Slot( + uri=LINKML.all_of, + name="class_expression_all_of", + curie=LINKML.curie("all_of"), + model_uri=LINKML.class_expression_all_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]], +) + +slots.class_expression_exactly_one_of = Slot( + uri=LINKML.exactly_one_of, + name="class_expression_exactly_one_of", + curie=LINKML.curie("exactly_one_of"), + model_uri=LINKML.class_expression_exactly_one_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]], +) + +slots.class_expression_none_of = Slot( + uri=LINKML.none_of, + name="class_expression_none_of", + curie=LINKML.curie("none_of"), + model_uri=LINKML.class_expression_none_of, + domain=None, + range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]], +) + +slots.class_definition_is_a = Slot( + uri=LINKML.is_a, + name="class_definition_is_a", + curie=LINKML.curie("is_a"), + model_uri=LINKML.class_definition_is_a, + domain=ClassDefinition, + range=Optional[Union[str, ClassDefinitionName]], +) + +slots.class_definition_mixins = Slot( + uri=LINKML.mixins, + name="class_definition_mixins", + curie=LINKML.curie("mixins"), + model_uri=LINKML.class_definition_mixins, + domain=ClassDefinition, + range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]], +) + +slots.class_definition_apply_to = Slot( + uri=LINKML.apply_to, + name="class_definition_apply_to", + curie=LINKML.curie("apply_to"), + model_uri=LINKML.class_definition_apply_to, + domain=ClassDefinition, + range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]], +) + +slots.class_definition_rules = Slot( + uri=SH.rule, + name="class_definition_rules", + curie=SH.curie("rule"), + model_uri=LINKML.class_definition_rules, + domain=ClassDefinition, + range=Optional[Union[Union[dict, "ClassRule"], list[Union[dict, "ClassRule"]]]], +) + +slots.class_definition_disjoint_with = Slot( + uri=LINKML.disjoint_with, + name="class_definition_disjoint_with", + curie=LINKML.curie("disjoint_with"), + model_uri=LINKML.class_definition_disjoint_with, + domain=ClassDefinition, + range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]], +) + +slots.class_definition_union_of = Slot( + uri=LINKML.union_of, + name="class_definition_union_of", + curie=LINKML.curie("union_of"), + model_uri=LINKML.class_definition_union_of, + domain=ClassDefinition, + range=Optional[Union[Union[str, ClassDefinitionName], list[Union[str, ClassDefinitionName]]]], +) + +slots.permissible_value_is_a = Slot( + uri=LINKML.is_a, + name="permissible_value_is_a", + curie=LINKML.curie("is_a"), + model_uri=LINKML.permissible_value_is_a, + domain=PermissibleValue, + range=Optional[Union[str, PermissibleValueText]], +) + +slots.permissible_value_mixins = Slot( + uri=LINKML.mixins, + name="permissible_value_mixins", + curie=LINKML.curie("mixins"), + model_uri=LINKML.permissible_value_mixins, + domain=PermissibleValue, + range=Optional[Union[Union[str, PermissibleValueText], list[Union[str, PermissibleValueText]]]], +) diff --git a/linkml_runtime/linkml_model/types.py b/linkml_runtime/linkml_model/types.py index f35140bf..8edc121c 100644 --- a/linkml_runtime/linkml_model/types.py +++ b/linkml_runtime/linkml_model/types.py @@ -8,22 +8,35 @@ from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import Bool, Curie, Decimal, ElementIdentifier, NCName, NodeIdentifier, URI, URIorCURIE, XSDDate, XSDDateTime, XSDTime +from linkml_runtime.utils.metamodelcore import ( + URI, + Bool, + Curie, + Decimal, + ElementIdentifier, + NCName, + NodeIdentifier, + URIorCURIE, + XSDDate, + XSDDateTime, + XSDTime, +) metamodel_version = "1.7.0" version = None # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SHEX = CurieNamespace('shex', 'http://www.w3.org/ns/shex#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SHEX = CurieNamespace("shex", "http://www.w3.org/ns/shex#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = LINKML # Types class String(str): - """ A character string """ + """A character string""" + type_class_uri = XSD["string"] type_class_curie = "xsd:string" type_name = "string" @@ -31,7 +44,8 @@ class String(str): class Integer(int): - """ An integer """ + """An integer""" + type_class_uri = XSD["integer"] type_class_curie = "xsd:integer" type_name = "integer" @@ -39,7 +53,8 @@ class Integer(int): class Boolean(Bool): - """ A binary (true or false) value """ + """A binary (true or false) value""" + type_class_uri = XSD["boolean"] type_class_curie = "xsd:boolean" type_name = "boolean" @@ -47,7 +62,8 @@ class Boolean(Bool): class Float(float): - """ A real number that conforms to the xsd:float specification """ + """A real number that conforms to the xsd:float specification""" + type_class_uri = XSD["float"] type_class_curie = "xsd:float" type_name = "float" @@ -55,7 +71,8 @@ class Float(float): class Double(float): - """ A real number that conforms to the xsd:double specification """ + """A real number that conforms to the xsd:double specification""" + type_class_uri = XSD["double"] type_class_curie = "xsd:double" type_name = "double" @@ -63,7 +80,8 @@ class Double(float): class Decimal(Decimal): - """ A real number with arbitrary precision that conforms to the xsd:decimal specification """ + """A real number with arbitrary precision that conforms to the xsd:decimal specification""" + type_class_uri = XSD["decimal"] type_class_curie = "xsd:decimal" type_name = "decimal" @@ -71,7 +89,8 @@ class Decimal(Decimal): class Time(XSDTime): - """ A time object represents a (local) time of day, independent of any particular day """ + """A time object represents a (local) time of day, independent of any particular day""" + type_class_uri = XSD["time"] type_class_curie = "xsd:time" type_name = "time" @@ -79,7 +98,8 @@ class Time(XSDTime): class Date(XSDDate): - """ a date (year, month and day) in an idealized calendar """ + """a date (year, month and day) in an idealized calendar""" + type_class_uri = XSD["date"] type_class_curie = "xsd:date" type_name = "date" @@ -87,7 +107,8 @@ class Date(XSDDate): class Datetime(XSDDateTime): - """ The combination of a date and time """ + """The combination of a date and time""" + type_class_uri = XSD["dateTime"] type_class_curie = "xsd:dateTime" type_name = "datetime" @@ -95,7 +116,8 @@ class Datetime(XSDDateTime): class DateOrDatetime(str): - """ Either a date or a datetime """ + """Either a date or a datetime""" + type_class_uri = LINKML["DateOrDatetime"] type_class_curie = "linkml:DateOrDatetime" type_name = "date_or_datetime" @@ -103,7 +125,8 @@ class DateOrDatetime(str): class Uriorcurie(URIorCURIE): - """ a URI or a CURIE """ + """a URI or a CURIE""" + type_class_uri = XSD["anyURI"] type_class_curie = "xsd:anyURI" type_name = "uriorcurie" @@ -111,7 +134,8 @@ class Uriorcurie(URIorCURIE): class Curie(Curie): - """ a compact URI """ + """a compact URI""" + type_class_uri = XSD["string"] type_class_curie = "xsd:string" type_name = "curie" @@ -119,7 +143,8 @@ class Curie(Curie): class Uri(URI): - """ a complete URI """ + """a complete URI""" + type_class_uri = XSD["anyURI"] type_class_curie = "xsd:anyURI" type_name = "uri" @@ -127,7 +152,8 @@ class Uri(URI): class Ncname(NCName): - """ Prefix part of CURIE """ + """Prefix part of CURIE""" + type_class_uri = XSD["string"] type_class_curie = "xsd:string" type_name = "ncname" @@ -135,7 +161,8 @@ class Ncname(NCName): class Objectidentifier(ElementIdentifier): - """ A URI or CURIE that represents an object in the model. """ + """A URI or CURIE that represents an object in the model.""" + type_class_uri = SHEX["iri"] type_class_curie = "shex:iri" type_name = "objectidentifier" @@ -143,7 +170,8 @@ class Objectidentifier(ElementIdentifier): class Nodeidentifier(NodeIdentifier): - """ A URI, CURIE or BNODE that represents a node in a model. """ + """A URI, CURIE or BNODE that represents a node in a model.""" + type_class_uri = SHEX["nonLiteral"] type_class_curie = "shex:nonLiteral" type_name = "nodeidentifier" @@ -151,7 +179,8 @@ class Nodeidentifier(NodeIdentifier): class Jsonpointer(str): - """ A string encoding a JSON Pointer. The value of the string MUST conform to JSON Point syntax and SHOULD dereference to a valid object within the current instance document when encoded in tree form. """ + """A string encoding a JSON Pointer. The value of the string MUST conform to JSON Point syntax and SHOULD dereference to a valid object within the current instance document when encoded in tree form.""" + type_class_uri = XSD["string"] type_class_curie = "xsd:string" type_name = "jsonpointer" @@ -159,7 +188,8 @@ class Jsonpointer(str): class Jsonpath(str): - """ A string encoding a JSON Path. The value of the string MUST conform to JSON Point syntax and SHOULD dereference to zero or more valid objects within the current instance document when encoded in tree form. """ + """A string encoding a JSON Path. The value of the string MUST conform to JSON Point syntax and SHOULD dereference to zero or more valid objects within the current instance document when encoded in tree form.""" + type_class_uri = XSD["string"] type_class_curie = "xsd:string" type_name = "jsonpath" @@ -167,7 +197,8 @@ class Jsonpath(str): class Sparqlpath(str): - """ A string encoding a SPARQL Property Path. The value of the string MUST conform to SPARQL syntax and SHOULD dereference to zero or more valid objects within the current instance document when encoded as RDF. """ + """A string encoding a SPARQL Property Path. The value of the string MUST conform to SPARQL syntax and SHOULD dereference to zero or more valid objects within the current instance document when encoded as RDF.""" + type_class_uri = XSD["string"] type_class_curie = "xsd:string" type_name = "sparqlpath" @@ -177,13 +208,9 @@ class Sparqlpath(str): # Class references - - # Enumerations # Slots class slots: pass - - diff --git a/linkml_runtime/linkml_model/units.py b/linkml_runtime/linkml_model/units.py index 0083d3a7..e6dffc25 100644 --- a/linkml_runtime/linkml_model/units.py +++ b/linkml_runtime/linkml_model/units.py @@ -20,14 +20,14 @@ version = None # Namespaces -IAO = CurieNamespace('IAO', 'http://purl.obolibrary.org/obo/IAO_') -OIO = CurieNamespace('OIO', 'http://www.geneontology.org/formats/oboInOwl#') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -QUDT = CurieNamespace('qudt', 'http://qudt.org/schema/qudt/') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +IAO = CurieNamespace("IAO", "http://purl.obolibrary.org/obo/IAO_") +OIO = CurieNamespace("OIO", "http://www.geneontology.org/formats/oboInOwl#") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +QUDT = CurieNamespace("qudt", "http://qudt.org/schema/qudt/") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = LINKML @@ -36,13 +36,13 @@ # Class references - @dataclass class UnitOfMeasure(YAMLRoot): """ A unit of measure, or unit, is a particular quantity value that has been chosen as a scale for measuring other quantities the same kind (more generally of equivalent dimension). """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = QUDT["Unit"] @@ -95,26 +95,75 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.unit = Slot(uri=QUDT.unit, name="unit", curie=QUDT.curie('unit'), - model_uri=LINKML.unit, domain=None, range=Optional[Union[dict, UnitOfMeasure]]) - -slots.ucum_code = Slot(uri=QUDT.ucumCode, name="ucum_code", curie=QUDT.curie('ucumCode'), - model_uri=LINKML.ucum_code, domain=UnitOfMeasure, range=Optional[str]) - -slots.derivation = Slot(uri=LINKML.derivation, name="derivation", curie=LINKML.curie('derivation'), - model_uri=LINKML.derivation, domain=None, range=Optional[str]) - -slots.has_quantity_kind = Slot(uri=QUDT.hasQuantityKind, name="has_quantity_kind", curie=QUDT.curie('hasQuantityKind'), - model_uri=LINKML.has_quantity_kind, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.iec61360code = Slot(uri=QUDT.iec61360Code, name="iec61360code", curie=QUDT.curie('iec61360Code'), - model_uri=LINKML.iec61360code, domain=None, range=Optional[str]) - -slots.symbol = Slot(uri=QUDT.symbol, name="symbol", curie=QUDT.curie('symbol'), - model_uri=LINKML.symbol, domain=None, range=Optional[str]) - -slots.abbreviation = Slot(uri=QUDT.abbreviation, name="abbreviation", curie=QUDT.curie('abbreviation'), - model_uri=LINKML.abbreviation, domain=None, range=Optional[str]) -slots.descriptive_name = Slot(uri=RDFS.label, name="descriptive_name", curie=RDFS.curie('label'), - model_uri=LINKML.descriptive_name, domain=None, range=Optional[str]) +slots.unit = Slot( + uri=QUDT.unit, + name="unit", + curie=QUDT.curie("unit"), + model_uri=LINKML.unit, + domain=None, + range=Optional[Union[dict, UnitOfMeasure]], +) + +slots.ucum_code = Slot( + uri=QUDT.ucumCode, + name="ucum_code", + curie=QUDT.curie("ucumCode"), + model_uri=LINKML.ucum_code, + domain=UnitOfMeasure, + range=Optional[str], +) + +slots.derivation = Slot( + uri=LINKML.derivation, + name="derivation", + curie=LINKML.curie("derivation"), + model_uri=LINKML.derivation, + domain=None, + range=Optional[str], +) + +slots.has_quantity_kind = Slot( + uri=QUDT.hasQuantityKind, + name="has_quantity_kind", + curie=QUDT.curie("hasQuantityKind"), + model_uri=LINKML.has_quantity_kind, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.iec61360code = Slot( + uri=QUDT.iec61360Code, + name="iec61360code", + curie=QUDT.curie("iec61360Code"), + model_uri=LINKML.iec61360code, + domain=None, + range=Optional[str], +) + +slots.symbol = Slot( + uri=QUDT.symbol, + name="symbol", + curie=QUDT.curie("symbol"), + model_uri=LINKML.symbol, + domain=None, + range=Optional[str], +) + +slots.abbreviation = Slot( + uri=QUDT.abbreviation, + name="abbreviation", + curie=QUDT.curie("abbreviation"), + model_uri=LINKML.abbreviation, + domain=None, + range=Optional[str], +) + +slots.descriptive_name = Slot( + uri=RDFS.label, + name="descriptive_name", + curie=RDFS.curie("label"), + model_uri=LINKML.descriptive_name, + domain=None, + range=Optional[str], +) diff --git a/linkml_runtime/linkml_model/validation.py b/linkml_runtime/linkml_model/validation.py index 6c4a7615..b4677bb6 100644 --- a/linkml_runtime/linkml_model/validation.py +++ b/linkml_runtime/linkml_model/validation.py @@ -22,16 +22,16 @@ version = None # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -OWL = CurieNamespace('owl', 'http://www.w3.org/2002/07/owl#') -PAV = CurieNamespace('pav', 'http://purl.org/pav/') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -REPORTING = CurieNamespace('reporting', 'https://w3id.org/linkml/report') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SH = CurieNamespace('sh', 'https://w3id.org/shacl/') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +OWL = CurieNamespace("owl", "http://www.w3.org/2002/07/owl#") +PAV = CurieNamespace("pav", "http://purl.org/pav/") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +REPORTING = CurieNamespace("reporting", "https://w3id.org/linkml/report") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SH = CurieNamespace("sh", "https://w3id.org/shacl/") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = REPORTING @@ -40,12 +40,12 @@ # Class references - @dataclass class ValidationReport(YAMLRoot): """ A report object """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SH["ValidationReport"] @@ -68,6 +68,7 @@ class ValidationResult(YAMLRoot): """ An individual result arising from validation of a data instance using a particular rule """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SH["ValidationResult"] @@ -121,74 +122,131 @@ class ProblemType(EnumDefinitionImpl): undeclared_slot = PermissibleValue( text="undeclared_slot", - description="Applies when a slot is used in data but the slot is undeclared in the datamodel") + description="Applies when a slot is used in data but the slot is undeclared in the datamodel", + ) inapplicable_slot = PermissibleValue( text="inapplicable_slot", - description="""Applies when a slot is used in an instance of a class where the slot is not applicable for that class""") + description="""Applies when a slot is used in an instance of a class where the slot is not applicable for that class""", + ) missing_slot_value = PermissibleValue( text="missing_slot_value", - description="Applies when an instance of a class has a required slot which is not filled in") + description="Applies when an instance of a class has a required slot which is not filled in", + ) slot_range_violation = PermissibleValue( text="slot_range_violation", - description="Applies when the value of a slot is inconsistent with the declared range") - max_count_violation = PermissibleValue( - text="max_count_violation", - meaning=SH["MaxCountConstraintComponent"]) - parsing_error = PermissibleValue( - text="parsing_error", - description="The data could not be parsed") + description="Applies when the value of a slot is inconsistent with the declared range", + ) + max_count_violation = PermissibleValue(text="max_count_violation", meaning=SH["MaxCountConstraintComponent"]) + parsing_error = PermissibleValue(text="parsing_error", description="The data could not be parsed") _defn = EnumDefinition( name="ProblemType", ) + class SeverityOptions(EnumDefinitionImpl): FATAL = PermissibleValue(text="FATAL") - ERROR = PermissibleValue( - text="ERROR", - meaning=SH["Violation"]) - WARNING = PermissibleValue( - text="WARNING", - meaning=SH["Warning"]) - INFO = PermissibleValue( - text="INFO", - meaning=SH["Info"]) + ERROR = PermissibleValue(text="ERROR", meaning=SH["Violation"]) + WARNING = PermissibleValue(text="WARNING", meaning=SH["Warning"]) + INFO = PermissibleValue(text="INFO", meaning=SH["Info"]) _defn = EnumDefinition( name="SeverityOptions", ) + # Slots class slots: pass -slots.type = Slot(uri=SH.sourceConstraintComponent, name="type", curie=SH.curie('sourceConstraintComponent'), - model_uri=REPORTING.type, domain=None, range=Optional[Union[str, NodeIdentifier]]) - -slots.subject = Slot(uri=SH.focusNode, name="subject", curie=SH.curie('focusNode'), - model_uri=REPORTING.subject, domain=None, range=Optional[Union[str, NodeIdentifier]]) - -slots.instantiates = Slot(uri=REPORTING.instantiates, name="instantiates", curie=REPORTING.curie('instantiates'), - model_uri=REPORTING.instantiates, domain=None, range=Optional[Union[str, NodeIdentifier]]) - -slots.predicate = Slot(uri=REPORTING.predicate, name="predicate", curie=REPORTING.curie('predicate'), - model_uri=REPORTING.predicate, domain=None, range=Optional[Union[str, NodeIdentifier]]) - -slots.object = Slot(uri=SH.value, name="object", curie=SH.curie('value'), - model_uri=REPORTING.object, domain=None, range=Optional[Union[str, NodeIdentifier]]) - -slots.object_str = Slot(uri=REPORTING.object_str, name="object_str", curie=REPORTING.curie('object_str'), - model_uri=REPORTING.object_str, domain=None, range=Optional[str]) - -slots.node_source = Slot(uri=REPORTING.node_source, name="node_source", curie=REPORTING.curie('node_source'), - model_uri=REPORTING.node_source, domain=None, range=Optional[Union[str, NodeIdentifier]]) - -slots.severity = Slot(uri=REPORTING.severity, name="severity", curie=REPORTING.curie('severity'), - model_uri=REPORTING.severity, domain=None, range=Optional[Union[str, "SeverityOptions"]]) - -slots.info = Slot(uri=REPORTING.info, name="info", curie=REPORTING.curie('info'), - model_uri=REPORTING.info, domain=None, range=Optional[str]) -slots.validationReport__results = Slot(uri=REPORTING.results, name="validationReport__results", curie=REPORTING.curie('results'), - model_uri=REPORTING.validationReport__results, domain=None, range=Optional[Union[Union[dict, ValidationResult], list[Union[dict, ValidationResult]]]]) +slots.type = Slot( + uri=SH.sourceConstraintComponent, + name="type", + curie=SH.curie("sourceConstraintComponent"), + model_uri=REPORTING.type, + domain=None, + range=Optional[Union[str, NodeIdentifier]], +) + +slots.subject = Slot( + uri=SH.focusNode, + name="subject", + curie=SH.curie("focusNode"), + model_uri=REPORTING.subject, + domain=None, + range=Optional[Union[str, NodeIdentifier]], +) + +slots.instantiates = Slot( + uri=REPORTING.instantiates, + name="instantiates", + curie=REPORTING.curie("instantiates"), + model_uri=REPORTING.instantiates, + domain=None, + range=Optional[Union[str, NodeIdentifier]], +) + +slots.predicate = Slot( + uri=REPORTING.predicate, + name="predicate", + curie=REPORTING.curie("predicate"), + model_uri=REPORTING.predicate, + domain=None, + range=Optional[Union[str, NodeIdentifier]], +) + +slots.object = Slot( + uri=SH.value, + name="object", + curie=SH.curie("value"), + model_uri=REPORTING.object, + domain=None, + range=Optional[Union[str, NodeIdentifier]], +) + +slots.object_str = Slot( + uri=REPORTING.object_str, + name="object_str", + curie=REPORTING.curie("object_str"), + model_uri=REPORTING.object_str, + domain=None, + range=Optional[str], +) + +slots.node_source = Slot( + uri=REPORTING.node_source, + name="node_source", + curie=REPORTING.curie("node_source"), + model_uri=REPORTING.node_source, + domain=None, + range=Optional[Union[str, NodeIdentifier]], +) + +slots.severity = Slot( + uri=REPORTING.severity, + name="severity", + curie=REPORTING.curie("severity"), + model_uri=REPORTING.severity, + domain=None, + range=Optional[Union[str, "SeverityOptions"]], +) + +slots.info = Slot( + uri=REPORTING.info, + name="info", + curie=REPORTING.curie("info"), + model_uri=REPORTING.info, + domain=None, + range=Optional[str], +) + +slots.validationReport__results = Slot( + uri=REPORTING.results, + name="validationReport__results", + curie=REPORTING.curie("results"), + model_uri=REPORTING.validationReport__results, + domain=None, + range=Optional[Union[Union[dict, ValidationResult], list[Union[dict, ValidationResult]]]], +) diff --git a/linkml_runtime/loaders/__init__.py b/linkml_runtime/loaders/__init__.py index 1fe4395d..ce41824a 100644 --- a/linkml_runtime/loaders/__init__.py +++ b/linkml_runtime/loaders/__init__.py @@ -1,9 +1,9 @@ +from linkml_runtime.loaders.csv_loader import CSVLoader from linkml_runtime.loaders.json_loader import JSONLoader from linkml_runtime.loaders.rdf_loader import RDFLoader from linkml_runtime.loaders.rdflib_loader import RDFLibLoader from linkml_runtime.loaders.tsv_loader import TSVLoader from linkml_runtime.loaders.yaml_loader import YAMLLoader -from linkml_runtime.loaders.csv_loader import CSVLoader json_loader = JSONLoader() rdf_loader = RDFLoader() diff --git a/linkml_runtime/loaders/context_flattener.py b/linkml_runtime/loaders/context_flattener.py index dbcc814c..4bf0b686 100644 --- a/linkml_runtime/loaders/context_flattener.py +++ b/linkml_runtime/loaders/context_flattener.py @@ -8,7 +8,7 @@ def flatten_dict(ctxt: str, base: str, seen: Optional[list[str]] = None) -> dict def map_context(ctxt_ent: Union[str, dict, list], seen: list[str]) -> Union[dict, list]: if isinstance(ctxt_ent, str): ent_dict = flatten_dict(ctxt_ent, base, seen) - return ent_dict['@context'] if '@context' in ent_dict else ent_dict + return ent_dict["@context"] if "@context" in ent_dict else ent_dict elif isinstance(ctxt_ent, list): return [map_context(clent, seen) for clent in ctxt_ent] else: @@ -17,9 +17,9 @@ def map_context(ctxt_ent: Union[str, dict, list], seen: list[str]) -> Union[dict def map_dict(inp: dict, seen: list[str]) -> dict: rval = dict() for k, v in inp.items(): - if k == '@context': + if k == "@context": v = map_context(v, seen) - elif k == '@import': + elif k == "@import": v = {} elif isinstance(v, dict): v = map_dict(v, seen) @@ -39,7 +39,7 @@ def map_dict(inp: dict, seen: list[str]) -> dict: def flatten(ctxt: str, base: str) -> str: - print('_'*10 + f' Flattening {os.path.join(base, ctxt)}') + print("_" * 10 + f" Flattening {os.path.join(base, ctxt)}") return json.dumps(flatten_dict(ctxt, base), indent=2) diff --git a/linkml_runtime/loaders/csv_loader.py b/linkml_runtime/loaders/csv_loader.py index f8dc2cad..a7aef2e9 100644 --- a/linkml_runtime/loaders/csv_loader.py +++ b/linkml_runtime/loaders/csv_loader.py @@ -1,7 +1,8 @@ from linkml_runtime.loaders.delimited_file_loader import DelimitedFileLoader + class CSVLoader(DelimitedFileLoader): - + @property def delimiter(self): return "," diff --git a/linkml_runtime/loaders/delimited_file_loader.py b/linkml_runtime/loaders/delimited_file_loader.py index a3d965d1..15fdd55d 100644 --- a/linkml_runtime/loaders/delimited_file_loader.py +++ b/linkml_runtime/loaders/delimited_file_loader.py @@ -1,16 +1,17 @@ -from abc import ABC, abstractmethod -from json_flattener import unflatten_from_csv, GlobalConfig import json +from abc import ABC, abstractmethod from typing import Union -from linkml_runtime.utils.yamlutils import YAMLRoot + +from json_flattener import GlobalConfig, unflatten_from_csv from pydantic import BaseModel -from linkml_runtime.loaders.loader_root import Loader +from linkml_runtime.linkml_model.meta import SchemaDefinition, SlotDefinitionName from linkml_runtime.loaders.json_loader import JSONLoader -from linkml_runtime.linkml_model.meta import SlotDefinitionName, SchemaDefinition -from linkml_runtime.utils.yamlutils import YAMLRoot -from linkml_runtime.utils.schemaview import SchemaView +from linkml_runtime.loaders.loader_root import Loader from linkml_runtime.utils.csvutils import get_configmap +from linkml_runtime.utils.schemaview import SchemaView +from linkml_runtime.utils.yamlutils import YAMLRoot + class DelimitedFileLoader(Loader, ABC): @@ -19,45 +20,55 @@ class DelimitedFileLoader(Loader, ABC): def delimiter(self): pass - def load_as_dict(self, - source: str, - index_slot: SlotDefinitionName = None, - schema: SchemaDefinition = None, - schemaview: SchemaView = None, - **kwargs) -> Union[dict, list[dict]]: + def load_as_dict( + self, + source: str, + index_slot: SlotDefinitionName = None, + schema: SchemaDefinition = None, + schemaview: SchemaView = None, + **kwargs, + ) -> Union[dict, list[dict]]: json_str = self._get_json_str_to_load(source, index_slot, schema, schemaview, **kwargs) return JSONLoader().load_as_dict(json_str) def load_any(self, *args, **kwargs) -> Union[YAMLRoot, list[YAMLRoot]]: return self.load(*args, **kwargs) - def loads(self, input, - target_class: type[Union[BaseModel, YAMLRoot]], - index_slot: SlotDefinitionName = None, - schema: SchemaDefinition = None, - schemaview: SchemaView = None, - **kwargs) -> str: + def loads( + self, + input, + target_class: type[Union[BaseModel, YAMLRoot]], + index_slot: SlotDefinitionName = None, + schema: SchemaDefinition = None, + schemaview: SchemaView = None, + **kwargs, + ) -> str: json_str = self._get_json_str_to_load(input, index_slot, schema, schemaview, **kwargs) return JSONLoader().loads(json_str, target_class=target_class) - def load(self, source: str, - target_class: type[Union[BaseModel, YAMLRoot]], - index_slot: SlotDefinitionName = None, - schema: SchemaDefinition = None, - schemaview: SchemaView = None, - **kwargs) -> str: + def load( + self, + source: str, + target_class: type[Union[BaseModel, YAMLRoot]], + index_slot: SlotDefinitionName = None, + schema: SchemaDefinition = None, + schemaview: SchemaView = None, + **kwargs, + ) -> str: json_str = self._get_json_str_to_load(source, index_slot, schema, schemaview, **kwargs) return JSONLoader().loads(json_str, target_class=target_class) - def _get_json_str_to_load(self, - input, - index_slot: SlotDefinitionName = None, - schema: SchemaDefinition = None, - schemaview: SchemaView = None, - **kwargs): + def _get_json_str_to_load( + self, + input, + index_slot: SlotDefinitionName = None, + schema: SchemaDefinition = None, + schemaview: SchemaView = None, + **kwargs, + ): if schemaview is None: schemaview = SchemaView(schema) configmap = get_configmap(schemaview, index_slot) config = GlobalConfig(key_configs=configmap, csv_delimiter=self.delimiter) objs = unflatten_from_csv(input, config=config, **kwargs) - return json.dumps({index_slot: objs}) \ No newline at end of file + return json.dumps({index_slot: objs}) diff --git a/linkml_runtime/loaders/json_loader.py b/linkml_runtime/loaders/json_loader.py index 6808cc2a..4c3dda82 100644 --- a/linkml_runtime/loaders/json_loader.py +++ b/linkml_runtime/loaders/json_loader.py @@ -1,39 +1,45 @@ import json import logging from pathlib import Path -from typing import Union, TextIO, Optional +from typing import Optional, TextIO, Union from hbreader import FileInfo +from pydantic import BaseModel from linkml_runtime.loaders.loader_root import Loader from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel logger = logging.getLogger(__name__) class JSONLoader(Loader): - def load_as_dict(self, - source: Union[str, dict, TextIO], - *, - base_dir: Optional[str] = None, - metadata: Optional[FileInfo] = None) -> Union[dict, list[dict]]: - data = self._read_source(source, base_dir=base_dir, metadata=metadata, accept_header="application/ld+json, application/json, text/json") + def load_as_dict( + self, source: Union[str, dict, TextIO], *, base_dir: Optional[str] = None, metadata: Optional[FileInfo] = None + ) -> Union[dict, list[dict]]: + data = self._read_source( + source, + base_dir=base_dir, + metadata=metadata, + accept_header="application/ld+json, application/json, text/json", + ) data_as_dict = json.loads(data) if isinstance(data, str) else data return self.json_clean(data_as_dict) - def load_any(self, - source: Union[str, dict, TextIO, Path], - target_class: type[Union[BaseModel, YAMLRoot]], - *, - base_dir: Optional[str] = None, - metadata: Optional[FileInfo] = None, - **_) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: + def load_any( + self, + source: Union[str, dict, TextIO, Path], + target_class: type[Union[BaseModel, YAMLRoot]], + *, + base_dir: Optional[str] = None, + metadata: Optional[FileInfo] = None, + **_, + ) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: """ Load the JSON in source into the python target_class structure - :param source: JSON data source. Can be a URL, a file name, a JSON string, a resolveable filepath or an existing graph + :param source: JSON data source. Can be a URL, a file name, a JSON string, a resolveable filepath, + or an existing graph :param target_class: LinkML class to load the JSON into :param base_dir: Base directory that can be used if file name or URL. This is copied into metadata if present :param metadata: source information. Used by some loaders to record where information came from @@ -54,7 +60,7 @@ def load_any(self, data_as_dict = self.load_as_dict(source, base_dir=base_dir, metadata=metadata) if isinstance(data_as_dict, dict): - typ = data_as_dict.pop('@type', None) + typ = data_as_dict.pop("@type", None) if typ and typ != target_class.__name__: logger.warning(f"Warning: input type mismatch. Expected: {target_class.__name__}, Actual: {typ}") diff --git a/linkml_runtime/loaders/loader_root.py b/linkml_runtime/loaders/loader_root.py index 6e8e5cc6..e9e7cfe8 100644 --- a/linkml_runtime/loaders/loader_root.py +++ b/linkml_runtime/loaders/loader_root.py @@ -1,19 +1,18 @@ from abc import ABC, abstractmethod -from pathlib import Path -from typing import TextIO, Union, Optional, Callable, Any from logging import getLogger +from pathlib import Path +from typing import Any, Callable, Optional, TextIO, Union -from pydantic import BaseModel from hbreader import FileInfo, hbread -from jsonasobj2 import as_dict, JsonObj +from jsonasobj2 import JsonObj, as_dict +from pydantic import BaseModel -from linkml_runtime.utils.yamlutils import YAMLRoot from linkml_runtime import URI_TO_LOCAL +from linkml_runtime.utils.yamlutils import YAMLRoot CACHE_SIZE = 1024 - class Loader(ABC): @staticmethod @@ -24,29 +23,32 @@ def json_clean(inp: Any) -> Any: :param inp: JSON-LD representation :return: JSON representation """ + def _is_empty(o) -> bool: return o is None or o == [] or o == {} if isinstance(inp, list): for e in [inp_e for inp_e in inp if _is_empty(inp_e)]: - del(inp[e]) + del inp[e] for e in inp: Loader.json_clean(e) elif isinstance(inp, dict): for k, v in list(inp.items()): - if k.startswith('@') or _is_empty(v): - del(inp[k]) + if k.startswith("@") or _is_empty(v): + del inp[k] else: Loader.json_clean(v) return inp - def load_source(self, - source: Union[str, dict, TextIO], - loader: Callable[[Union[str, dict], FileInfo], Optional[Union[dict, list]]], - target_class: Union[type[YAMLRoot], type[BaseModel]], - accept_header: Optional[str] = "text/plain, application/yaml;q=0.9", - metadata: Optional[FileInfo] = None) -> Optional[Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]]: - """ Base loader - convert a file, url, string, open file handle or dictionary into an instance + def load_source( + self, + source: Union[str, dict, TextIO], + loader: Callable[[Union[str, dict], FileInfo], Optional[Union[dict, list]]], + target_class: Union[type[YAMLRoot], type[BaseModel]], + accept_header: Optional[str] = "text/plain, application/yaml;q=0.9", + metadata: Optional[FileInfo] = None, + ) -> Optional[Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]]: + """Base loader - convert a file, url, string, open file handle or dictionary into an instance of target_class :param source: URL, file name, block of text, Existing Object or open file handle @@ -62,7 +64,6 @@ def load_source(self, data_as_dict = loader(data, metadata) return self._construct_target_class(data_as_dict, target_class=target_class) - def load(self, *args, **kwargs) -> Union[BaseModel, YAMLRoot]: """ Load source as an instance of target_class @@ -78,14 +79,21 @@ def load(self, *args, **kwargs) -> Union[BaseModel, YAMLRoot]: if isinstance(results, BaseModel) or isinstance(results, YAMLRoot): return results else: - raise ValueError(f'Result is not an instance of BaseModel or YAMLRoot: {type(results)}') - + raise ValueError(f"Result is not an instance of BaseModel or YAMLRoot: {type(results)}") + def load_as_dict(self, *args, **kwargs) -> Union[dict, list[dict]]: raise NotImplementedError() @abstractmethod - def load_any(self, source: Union[str, dict, TextIO, Path], target_class: type[Union[BaseModel, YAMLRoot]], *, base_dir: Optional[str] = None, - metadata: Optional[FileInfo] = None, **_) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: + def load_any( + self, + source: Union[str, dict, TextIO, Path], + target_class: type[Union[BaseModel, YAMLRoot]], + *, + base_dir: Optional[str] = None, + metadata: Optional[FileInfo] = None, + **_, + ) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: """ Load source as an instance of target_class, or list of instances of target_class @@ -98,7 +106,9 @@ def load_any(self, source: Union[str, dict, TextIO, Path], target_class: type[Un """ raise NotImplementedError() - def loads_any(self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, metadata: Optional[FileInfo] = None, **_) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: + def loads_any( + self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, metadata: Optional[FileInfo] = None, **_ + ) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: """ Load source as a string as an instance of target_class, or list of instances of target_class @param source: source @@ -109,7 +119,9 @@ def loads_any(self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], """ return self.load_any(source, target_class, metadata=metadata) - def loads(self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, metadata: Optional[FileInfo] = None, **_) -> Union[BaseModel, YAMLRoot]: + def loads( + self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, metadata: Optional[FileInfo] = None, **_ + ) -> Union[BaseModel, YAMLRoot]: """ Load source as a string :param source: source @@ -120,17 +132,17 @@ def loads(self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, """ return self.load(source, target_class, metadata=metadata) - def _construct_target_class(self, - data_as_dict: Union[dict, list[dict]], - target_class: Union[type[YAMLRoot], type[BaseModel]]) -> Optional[Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]]: + def _construct_target_class( + self, data_as_dict: Union[dict, list[dict]], target_class: Union[type[YAMLRoot], type[BaseModel]] + ) -> Optional[Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]]: if data_as_dict: if isinstance(data_as_dict, list): - if issubclass(target_class, YAMLRoot): - return [target_class(**as_dict(x)) for x in data_as_dict] - elif issubclass(target_class, BaseModel): - return [target_class.model_validate(as_dict(x)) for x in data_as_dict] - else: - raise ValueError(f'Cannot load list of {target_class}') + if issubclass(target_class, YAMLRoot): + return [target_class(**as_dict(x)) for x in data_as_dict] + elif issubclass(target_class, BaseModel): + return [target_class.model_validate(as_dict(x)) for x in data_as_dict] + else: + raise ValueError(f"Cannot load list of {target_class}") elif isinstance(data_as_dict, dict): if issubclass(target_class, BaseModel): return target_class.model_validate(data_as_dict) @@ -139,17 +151,18 @@ def _construct_target_class(self, elif isinstance(data_as_dict, JsonObj): return [target_class(**as_dict(x)) for x in data_as_dict] else: - raise ValueError(f'Unexpected type {data_as_dict}') + raise ValueError(f"Unexpected type {data_as_dict}") else: return None - - def _read_source(self, - source: Union[str, dict, TextIO], - *, - base_dir: Optional[str] = None, - metadata: Optional[FileInfo] = None, - accept_header: Optional[str] = "text/plain, application/yaml;q=0.9") -> Union[dict, str]: + def _read_source( + self, + source: Union[str, dict, TextIO], + *, + base_dir: Optional[str] = None, + metadata: Optional[FileInfo] = None, + accept_header: Optional[str] = "text/plain, application/yaml;q=0.9", + ) -> Union[dict, str]: if metadata is None: metadata = FileInfo() if base_dir and not metadata.base_path: @@ -162,11 +175,11 @@ def _read_source(self, source = str(URI_TO_LOCAL[str(source)]) except (TypeError, KeyError) as e: # Fine, use original `source` value - logger = getLogger('linkml_runtime.loaders.Loader') + logger = getLogger("linkml_runtime.loaders.Loader") logger.debug(f"Error converting stringlike source to local linkml file: {source}, got: {e}") data = hbread(source, metadata, base_dir, accept_header) else: data = source - return data \ No newline at end of file + return data diff --git a/linkml_runtime/loaders/rdf_loader.py b/linkml_runtime/loaders/rdf_loader.py index 8bc46ef0..35eab24b 100644 --- a/linkml_runtime/loaders/rdf_loader.py +++ b/linkml_runtime/loaders/rdf_loader.py @@ -1,13 +1,14 @@ -from typing import Union, TextIO, Optional +import json +from typing import Optional, TextIO, Union from hbreader import FileInfo -from linkml_runtime.loaders.loader_root import Loader -from linkml_runtime.utils.context_utils import CONTEXTS_PARAM_TYPE -from linkml_runtime.utils.yamlutils import YAMLRoot from pydantic import BaseModel from rdflib import Graph +from linkml_runtime.loaders.loader_root import Loader from linkml_runtime.loaders.requests_ssl_patch import no_ssl_verification +from linkml_runtime.utils.context_utils import CONTEXTS_PARAM_TYPE +from linkml_runtime.utils.yamlutils import YAMLRoot # TODO: figure out what mime types go here. I think we can find the complete set in rdflib RDF_MIME_TYPES = "application/x-turtle;q=0.9, application/rdf+n3;q=0.8, application/rdf+xml;q=0.5, text/plain;q=0.1" @@ -18,10 +19,16 @@ class RDFLoader(Loader): def load_any(self, *args, **kwargs) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: return self.load(*args, **kwargs) - - def load(self, source: Union[str, TextIO, Graph], target_class: type[Union[BaseModel, YAMLRoot]], *, base_dir: Optional[str] = None, - contexts: CONTEXTS_PARAM_TYPE = None, fmt: Optional[str] = 'turtle', - metadata: Optional[FileInfo] = None) -> Union[BaseModel, YAMLRoot]: + def load( + self, + source: Union[str, TextIO, Graph], + target_class: type[Union[BaseModel, YAMLRoot]], + *, + base_dir: Optional[str] = None, + contexts: CONTEXTS_PARAM_TYPE = None, + fmt: Optional[str] = "turtle", + metadata: Optional[FileInfo] = None, + ) -> Union[BaseModel, YAMLRoot]: """ Load the RDF in source into the python target_class structure :param source: RDF data source. Can be a URL, a file name, an RDF string, an open handle or an existing graph @@ -47,10 +54,10 @@ def loader(data: Union[str, dict], _: FileInfo) -> Optional[dict]: # on the way out # Also - if we don't pop type below, we need to act accordingly if isinstance(data, str): - if fmt != 'json-ld': + if fmt != "json-ld": g = Graph() g.parse(data=data, format=fmt) - jsonld_str = g.serialize(format='json-ld', indent=4) + jsonld_str = g.serialize(format="json-ld", indent=4) data = json.loads(jsonld_str) if not isinstance(data, dict): @@ -59,14 +66,14 @@ def loader(data: Union[str, dict], _: FileInfo) -> Optional[dict]: # TODO: determine whether jsonld.frame can handle something other than string input # TODO: see https://github.com/RDFLib/rdflib/issues/1727 # frame = {'@context': contexts, '@type': f'{target_class.__name__}'} - #data_as_dict = jsonld.frame(data, contexts) + # data_as_dict = jsonld.frame(data, contexts) data_as_dict = data else: data_as_dict = data - typ = data_as_dict.pop('@type', None) + typ = data_as_dict.pop("@type", None) # TODO: remove this when we get the Biolinkml issue fixed if not typ: - typ = data_as_dict.pop('type', None) + typ = data_as_dict.pop("type", None) if typ and typ != target_class.class_name: # TODO: connect this up with the logging facility or warning? print(f"Warning: input type mismatch. Expected: {target_class.__name__}, Actual: {typ}") @@ -79,10 +86,10 @@ def loader(data: Union[str, dict], _: FileInfo) -> Optional[dict]: # If the input is a graph, convert it to JSON-LD if isinstance(source, Graph): - source = pyld_jsonld_from_rdflib_graph(source) - jsonld_str = source.serialize(format='json-ld', indent=4) + source = pyld_jsonld_from_rdflib_graph(source) # noqa: F821 - no idea what this is + jsonld_str = source.serialize(format="json-ld", indent=4) source = json.loads(jsonld_str) - fmt = 'json-ld' + fmt = "json-ld" # While we may want to allow full SSL verification at some point, the general philosophy is that content forgery # is not going to be a serious problem. diff --git a/linkml_runtime/loaders/rdflib_loader.py b/linkml_runtime/loaders/rdflib_loader.py index 758d13e9..ad1b9afd 100644 --- a/linkml_runtime/loaders/rdflib_loader.py +++ b/linkml_runtime/loaders/rdflib_loader.py @@ -2,21 +2,21 @@ import urllib from copy import copy from dataclasses import dataclass -from typing import Optional, Any, Union, TextIO +from typing import Any, Optional, TextIO, Union from curies import Converter from hbreader import FileInfo +from pydantic import BaseModel from rdflib import Graph, URIRef -from rdflib.term import BNode, Literal from rdflib.namespace import RDF +from rdflib.term import BNode, Literal -from linkml_runtime import MappingError, DataNotFoundError -from linkml_runtime.linkml_model import ClassDefinitionName, TypeDefinition, EnumDefinition, ClassDefinition +from linkml_runtime import DataNotFoundError, MappingError +from linkml_runtime.linkml_model import ClassDefinition, ClassDefinitionName, EnumDefinition, TypeDefinition from linkml_runtime.loaders.loader_root import Loader from linkml_runtime.utils.formatutils import underscore from linkml_runtime.utils.schemaview import SchemaView, SlotDefinition from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel logger = logging.getLogger(__name__) @@ -24,18 +24,22 @@ VALID_SUBJECT = Union[URIRef, BNode] ANYDICT = dict[str, Any] + @dataclass class Pointer: obj: str + class RDFLibLoader(Loader): """ Loads objects from rdflib Graphs into the python target_class structure Note: this is a more complete replacement for rdf_loader """ + def from_rdf_graph( - self, graph: Graph, + self, + graph: Graph, schemaview: SchemaView, target_class: type[Union[BaseModel, YAMLRoot]], prefix_map: Union[dict[str, str], Converter, None] = None, @@ -51,7 +55,8 @@ def from_rdf_graph( :param schemaview: schema to which graph conforms :param target_class: class which root nodes should instantiate :param prefix_map: additional prefix mappings for data objects - :param ignore_unmapped_predicates: if True then a predicate that has no mapping to a slot does not raise an error + :param ignore_unmapped_predicates: + if True then a predicate that has no mapping to a slot does not raise an error :return: all instances of target class type """ namespaces = schemaview.namespaces() @@ -63,7 +68,7 @@ def from_rdf_graph( if c2.name in schemaview.class_ancestors(cn): continue else: - logger.error(f'Inconsistent URI to class map: {uri} -> {c2.name}, {c.name}') + logger.error(f"Inconsistent URI to class map: {uri} -> {c2.name}, {c.name}") uri_to_class_map[uri] = c # data prefix map: supplements or overrides existing schema prefix map if isinstance(prefix_map, Converter): @@ -77,7 +82,7 @@ def from_rdf_graph( target_class_uriref: URIRef = target_class.class_class_uri root_dicts: list[ANYDICT] = [] root_subjects: list[VALID_SUBJECT] = list(graph.subjects(RDF.type, target_class_uriref)) - logger.debug(f'ROOTS = {root_subjects}') + logger.debug(f"ROOTS = {root_subjects}") # Step 2: walk RDF graph starting from root subjects, constructing dict tree node_tuples_to_visit: list[tuple[VALID_SUBJECT, ClassDefinitionName]] ## nodes and their type still to visit node_tuples_to_visit = [(subject, target_class.class_name) for subject in root_subjects] @@ -103,20 +108,22 @@ def from_rdf_graph( if len(type_vals) > 0: type_classes = [uri_to_class_map[str(x)] for x in type_vals] if len(type_classes) > 1: - raise ValueError(f'Ambiguous types for {subject} == {type_classes}') - logger.info(f'Replacing {subject_class} with {type_classes}') + raise ValueError(f"Ambiguous types for {subject} == {type_classes}") + logger.info(f"Replacing {subject_class} with {type_classes}") subject_class = type_classes[0].name # process all triples for this node - for (_, p, o) in graph.triples((subject, None, None)): - processed_triples.add((subject,p,o)) - logger.debug(f' Processing triple {subject} {p} {o}, subject type = {subject_class}') + for _, p, o in graph.triples((subject, None, None)): + processed_triples.add((subject, p, o)) + logger.debug(f" Processing triple {subject} {p} {o}, subject type = {subject_class}") if p == RDF.type: - logger.debug(f'Ignoring RDF.type for {subject} {o}, we automatically infer this from {subject_class}') + logger.debug( + f"Ignoring RDF.type for {subject} {o}, we automatically infer this from {subject_class}" + ) elif p not in uri_to_slot: if ignore_unmapped_predicates: unmapped_predicates.add(p) else: - raise MappingError(f'No pred for {p} {type(p)}') + raise MappingError(f"No pred for {p} {type(p)}") else: slot = schemaview.induced_slot(uri_to_slot[p].name, subject_class) range_applicable_elements = schemaview.slot_applicable_range_elements(slot) @@ -124,13 +131,15 @@ def from_rdf_graph( slot_name = underscore(slot.name) if isinstance(o, Literal): if EnumDefinition.class_name in range_applicable_elements: - logger.debug(f'Assuming no meaning assigned for value {o} for Enum {slot.range}') + logger.debug(f"Assuming no meaning assigned for value {o} for Enum {slot.range}") elif TypeDefinition.class_name not in range_applicable_elements: - raise ValueError(f'Cannot map Literal {o} to a slot {slot.name} whose range {slot.range} is not a type;') + raise ValueError( + f"Cannot map Literal {o} to a slot {slot.name} whose range {slot.range} is not a type;" + ) v = o.value elif isinstance(o, BNode): if not is_inlined: - logger.error(f'blank nodes should be inlined; {slot_name}={o} in {subject}') + logger.error(f"blank nodes should be inlined; {slot_name}={o} in {subject}") v = Pointer(o) else: if ClassDefinition.class_name in range_applicable_elements: @@ -140,7 +149,7 @@ def from_rdf_graph( else: v = namespaces.curie_for(o) if v is None: - logger.debug(f'No CURIE for {p}={o} in {subject} [{subject_class}]') + logger.debug(f"No CURIE for {p}={o} in {subject} [{subject_class}]") v = str(o) elif EnumDefinition.class_name in range_applicable_elements: range_union_elements = schemaview.slot_range_as_union(slot) @@ -159,9 +168,11 @@ def from_rdf_graph( v = namespaces.curie_for(o) if v is None: v = str(o) - logger.debug(f'Casting {o} to string') + logger.debug(f"Casting {o} to string") else: - raise ValueError(f'Expected literal value ({range_applicable_elements}) for {slot_name}={o}') + raise ValueError( + f"Expected literal value ({range_applicable_elements}) for {slot_name}={o}" + ) if is_inlined: # the object of the triple may not yet be processed; # we store a pointer to o, and then replace this later @@ -178,27 +189,29 @@ def from_rdf_graph( if slot.range in schemaview.all_classes(): node_tuples_to_visit.append((o, ClassDefinitionName(slot.range))) if unmapped_predicates: - logger.info(f'Unmapped predicated: {unmapped_predicates}') + logger.info(f"Unmapped predicated: {unmapped_predicates}") unprocessed_triples = set(graph.triples((None, None, None))) - processed_triples - logger.info(f'Triple processed = {len(processed_triples)}, unprocessed = {len(unprocessed_triples)}') + logger.info(f"Triple processed = {len(processed_triples)}, unprocessed = {len(unprocessed_triples)}") if len(unprocessed_triples) > 0: if not allow_unprocessed_triples: for t in unprocessed_triples: - logger.warning(f' Unprocessed: {t}') - raise ValueError(f'Unprocessed triples: {len(unprocessed_triples)}') + logger.warning(f" Unprocessed: {t}") + raise ValueError(f"Unprocessed triples: {len(unprocessed_triples)}") + # Step 2: replace inline pointers with object dicts def repl(v): if isinstance(v, Pointer): v2 = obj_map[v.obj] if v2 is None: - raise Exception(f'No mapping for pointer {v}') + raise Exception(f"No mapping for pointer {v}") return v2 else: return v + objs_to_visit: list[ANYDICT] = copy(root_dicts) while len(objs_to_visit) > 0: obj = objs_to_visit.pop() - logger.debug(f'Replacing pointers for {obj}') + logger.debug(f"Replacing pointers for {obj}") for k, v in obj.items(): if v is None: continue @@ -219,13 +232,12 @@ def _get_id_dict(self, node: VALID_SUBJECT, schemaview: SchemaView, cn: ClassDef id_slot = schemaview.get_identifier_slot(cn) if not isinstance(node, BNode): id_val = self._uri_to_id(node, id_slot, schemaview) - #id_val = schemaview.namespaces().curie_for(node) - if id_val == None: + if id_val is None: id_val = str(node) return {id_slot.name: id_val} else: if id_slot is not None: - raise Exception(f'Unexpected blank node {node}, type {cn} expects {id_slot.name} identifier') + raise Exception(f"Unexpected blank node {node}, type {cn} expects {id_slot.name} identifier") return {} def _uri_to_id(self, node: VALID_SUBJECT, id_slot: SlotDefinition, schemaview: SchemaView) -> str: @@ -234,14 +246,14 @@ def _uri_to_id(self, node: VALID_SUBJECT, id_slot: SlotDefinition, schemaview: S else: return schemaview.namespaces().curie_for(node) - def load( self, source: Union[str, TextIO, Graph], - target_class: type[Union[BaseModel, YAMLRoot]], *, + target_class: type[Union[BaseModel, YAMLRoot]], + *, schemaview: SchemaView = None, prefix_map: Union[dict[str, str], Converter, None] = None, - fmt: Optional[str] = 'turtle', + fmt: Optional[str] = "turtle", metadata: Optional[FileInfo] = None, **kwargs, ) -> Union[BaseModel, YAMLRoot]: @@ -264,13 +276,13 @@ def load( g = source else: g = Graph() - if '\n' in source: + if "\n" in source: g.parse(data=source, format=fmt) else: g.parse(source, format=fmt) objs = self.from_rdf_graph(g, schemaview=schemaview, target_class=target_class, prefix_map=prefix_map, **kwargs) if len(objs) != 1: - raise DataNotFoundError(f'Got {len(objs)} of type {target_class} from source, expected exactly 1') + raise DataNotFoundError(f"Got {len(objs)} of type {target_class} from source, expected exactly 1") return objs[0] def loads(self, source: str, **kwargs) -> Union[BaseModel, YAMLRoot]: @@ -278,5 +290,3 @@ def loads(self, source: str, **kwargs) -> Union[BaseModel, YAMLRoot]: def load_any(self, source: str, **kwargs) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: return self.load(source, **kwargs) - - diff --git a/linkml_runtime/loaders/requests_ssl_patch.py b/linkml_runtime/loaders/requests_ssl_patch.py index 5395af7d..db4639ef 100644 --- a/linkml_runtime/loaders/requests_ssl_patch.py +++ b/linkml_runtime/loaders/requests_ssl_patch.py @@ -1,5 +1,5 @@ -import warnings import contextlib +import warnings import requests from urllib3.exceptions import InsecureRequestWarning @@ -19,7 +19,7 @@ def merge_environment_settings(self, url, proxies, stream, verify, cert): opened_adapters.add(self.get_adapter(url)) settings = old_merge_environment_settings(self, url, proxies, stream, verify, cert) - settings['verify'] = False + settings["verify"] = False return settings @@ -27,7 +27,7 @@ def merge_environment_settings(self, url, proxies, stream, verify, cert): try: with warnings.catch_warnings(): - warnings.simplefilter('ignore', InsecureRequestWarning) + warnings.simplefilter("ignore", InsecureRequestWarning) yield finally: requests.Session.merge_environment_settings = old_merge_environment_settings diff --git a/linkml_runtime/loaders/tsv_loader.py b/linkml_runtime/loaders/tsv_loader.py index 0d926321..bfc0a31a 100644 --- a/linkml_runtime/loaders/tsv_loader.py +++ b/linkml_runtime/loaders/tsv_loader.py @@ -1,7 +1,8 @@ from linkml_runtime.loaders.delimited_file_loader import DelimitedFileLoader + class TSVLoader(DelimitedFileLoader): - + @property def delimiter(self): return "\t" diff --git a/linkml_runtime/loaders/yaml_loader.py b/linkml_runtime/loaders/yaml_loader.py index fa33a280..30bb0821 100644 --- a/linkml_runtime/loaders/yaml_loader.py +++ b/linkml_runtime/loaders/yaml_loader.py @@ -1,13 +1,13 @@ import os from io import StringIO -from typing import Union, TextIO, Optional +from typing import Optional, TextIO, Union import yaml from hbreader import FileInfo +from pydantic import BaseModel from linkml_runtime.loaders.loader_root import Loader -from linkml_runtime.utils.yamlutils import YAMLRoot, DupCheckYamlLoader -from pydantic import BaseModel +from linkml_runtime.utils.yamlutils import DupCheckYamlLoader, YAMLRoot class YAMLLoader(Loader): @@ -15,16 +15,16 @@ class YAMLLoader(Loader): A Loader that is capable of instantiating LinkML data objects from a YAML file """ - def load_as_dict(self, - source: Union[str, dict, TextIO], - *, - base_dir: Optional[str] = None, - metadata: Optional[FileInfo] = None) -> Union[dict, list[dict]]: + def load_as_dict( + self, source: Union[str, dict, TextIO], *, base_dir: Optional[str] = None, metadata: Optional[FileInfo] = None + ) -> Union[dict, list[dict]]: if metadata is None: metadata = FileInfo() if base_dir and not metadata.base_path: metadata.base_path = base_dir - data = self._read_source(source, base_dir=base_dir, metadata=metadata, accept_header="text/yaml, application/yaml;q=0.9") + data = self._read_source( + source, base_dir=base_dir, metadata=metadata, accept_header="text/yaml, application/yaml;q=0.9" + ) if isinstance(data, str): data = StringIO(data) if metadata and metadata.source_file: @@ -33,15 +33,21 @@ def load_as_dict(self, else: return data - def load_any(self, - source: Union[str, dict, TextIO], - target_class: Union[type[YAMLRoot], type[BaseModel]], - *, base_dir: Optional[str] = None, - metadata: Optional[FileInfo] = None, **_) -> Union[YAMLRoot, list[YAMLRoot]]: + def load_any( + self, + source: Union[str, dict, TextIO], + target_class: Union[type[YAMLRoot], type[BaseModel]], + *, + base_dir: Optional[str] = None, + metadata: Optional[FileInfo] = None, + **_, + ) -> Union[YAMLRoot, list[YAMLRoot]]: data_as_dict = self.load_as_dict(source, base_dir=base_dir, metadata=metadata) return self._construct_target_class(data_as_dict, target_class) - def loads_any(self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, metadata: Optional[FileInfo] = None, **_) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: + def loads_any( + self, source: str, target_class: type[Union[BaseModel, YAMLRoot]], *, metadata: Optional[FileInfo] = None, **_ + ) -> Union[BaseModel, YAMLRoot, list[BaseModel], list[YAMLRoot]]: """ Load source as a string @param source: source diff --git a/linkml_runtime/processing/referencevalidator.py b/linkml_runtime/processing/referencevalidator.py index a167f634..3f2b8684 100644 --- a/linkml_runtime/processing/referencevalidator.py +++ b/linkml_runtime/processing/referencevalidator.py @@ -5,16 +5,17 @@ - `Part 5`_ of LinkML specification - `Part 6`_ of LinkML specification """ + +import datetime import decimal import re import sys +from collections.abc import Iterator from copy import copy from dataclasses import dataclass, field -import datetime from decimal import Decimal from enum import Enum -from typing import Any, Optional, Union, TextIO -from collections.abc import Iterator +from typing import Any, Optional, TextIO, Union import click import yaml @@ -22,38 +23,38 @@ from linkml_runtime import SchemaView from linkml_runtime.dumpers import yaml_dumper from linkml_runtime.linkml_model import ( - SlotDefinition, ClassDefinition, - EnumDefinition, - TypeDefinition, Element, + EnumDefinition, SchemaDefinition, + SlotDefinition, SlotDefinitionName, + TypeDefinition, ) from linkml_runtime.linkml_model.meta import ( AnonymousClassExpression, AnonymousSlotExpression, - ClassRule, ClassDefinitionName, + ClassRule, ) from linkml_runtime.processing.validation_datamodel import ( ConstraintType, - ValidationResult, ValidationConfiguration, + ValidationConfiguration, + ValidationResult, ) from linkml_runtime.utils import yamlutils from linkml_runtime.utils.eval_utils import eval_expr from linkml_runtime.utils.metamodelcore import ( - XSDTime, - Bool, - XSDDate, - URIorCURIE, URI, - NCName, + Bool, ElementIdentifier, + NCName, NodeIdentifier, + URIorCURIE, + XSDDate, + XSDTime, ) - # Mapping from either XSD types or LinkML type.base fields to Python types; # (the coerced type is the last element of the tuple, the others are # acceptable types) @@ -140,6 +141,7 @@ def _linearize_nested_list_column_order(nested_list): return result + class CollectionForm(Enum): """Form of a schema element. See Part 6 of the LinkML specification""" @@ -164,6 +166,7 @@ class Normalization: @dataclass class CollectionFormNormalization(Normalization): """A normalization that maps from one collection form to another""" + input_form: CollectionForm = None output_form: CollectionForm = None @@ -383,9 +386,7 @@ def normalize( report = Report() return self.normalize_slot_value(input_object, parent_slot, report) - def _create_index_slot( - self, target: Optional[str] = None, input_object: Any = None - ) -> SlotDefinition: + def _create_index_slot(self, target: Optional[str] = None, input_object: Any = None) -> SlotDefinition: """ Create a parent slot that points at the target element. @@ -403,9 +404,7 @@ def _create_index_slot( slot.multivalued = True return slot - def _schema_root( - self, target: Optional[str] = None - ) -> Optional[ClassDefinitionName]: + def _schema_root(self, target: Optional[str] = None) -> Optional[ClassDefinitionName]: if target is not None: return ClassDefinitionName(target) roots = [r.name for r in self.derived_schema.classes.values() if r.tree_root] @@ -413,9 +412,7 @@ def _schema_root( raise ValueError(f"Cannot normalize: {len(roots)} roots found") return roots[0] - def normalize_slot_value( - self, input_object: Any, parent_slot: SlotDefinition, report: Report - ) -> Any: + def normalize_slot_value(self, input_object: Any, parent_slot: SlotDefinition, report: Report) -> Any: pk_slot_name = None range_element = self._slot_range_element(parent_slot) # Infer collection form, and normalize to this form, if necessary @@ -429,9 +426,7 @@ def normalize_slot_value( # Validate new_report = Report() if parent_slot.required and not normalized_object: - report.add_problem( - ConstraintType.RequiredConstraint, parent_slot.range, str(input_object) - ) + report.add_problem(ConstraintType.RequiredConstraint, parent_slot.range, str(input_object)) if parent_slot.recommended and not normalized_object: report.add_problem( ConstraintType.RecommendedConstraint, @@ -442,8 +437,7 @@ def normalize_slot_value( if isinstance(normalized_object, dict) and parent_slot.multivalued: if not simple_dict_value_slot: output_object = { - k: self.normalize_instance(v, parent_slot, new_report) - for k, v in normalized_object.items() + k: self.normalize_instance(v, parent_slot, new_report) for k, v in normalized_object.items() } else: output_object = { @@ -453,21 +447,14 @@ def normalize_slot_value( elif _is_list_of_lists(normalized_object): raise NotImplementedError(f"List of Lists: {normalized_object}") elif isinstance(normalized_object, list): - output_object = [ - self.normalize_instance(v, parent_slot, new_report) - for v in normalized_object - ] + output_object = [self.normalize_instance(v, parent_slot, new_report) for v in normalized_object] else: # normalize an instance - output_object = self.normalize_instance( - normalized_object, parent_slot, new_report - ) + output_object = self.normalize_instance(normalized_object, parent_slot, new_report) report.combine(new_report) return output_object - def _is_dict_collection( - self, input_object: Any, parent_slot: SlotDefinition - ) -> bool: + def _is_dict_collection(self, input_object: Any, parent_slot: SlotDefinition) -> bool: if not isinstance(input_object, dict): return False if not parent_slot.multivalued: @@ -495,10 +482,7 @@ def infer_slot_collection_form(self, parent_slot: SlotDefinition) -> CollectionF if simple_dict_value_slot: return CollectionForm.SimpleDict # TODO: provide direct metamodel method - if ( - "expanded" in parent_slot.annotations - and parent_slot.annotations["expanded"].value - ): + if "expanded" in parent_slot.annotations and parent_slot.annotations["expanded"].value: return CollectionForm.ExpandedDict return CollectionForm.CompactDict @@ -623,9 +607,7 @@ def ensure_expanded_dict( if isinstance(input_object, dict): simple_dict_value_slot = self._slot_as_simple_dict_value_slot(parent_slot) if simple_dict_value_slot and any( - v - for v in input_object.values() - if v is not None and not isinstance(v, dict) + v for v in input_object.values() if v is not None and not isinstance(v, dict) ): # SimpleDict -> ExpandedDict report.add_collection_form_normalization( @@ -634,9 +616,7 @@ def ensure_expanded_dict( CollectionForm.ExpandedDict, ) return { - k: _add_pk( - _simple_to_dict(v, simple_dict_value_slot.name), pk_slot_name, k - ) + k: _add_pk(_simple_to_dict(v, simple_dict_value_slot.name), pk_slot_name, k) for k, v in input_object.items() } else: @@ -657,14 +637,10 @@ def ensure_compact_dict( CollectionForm.List, CollectionForm.CompactDict, ) - return { - v.get(pk_slot_name): _remove_pk(v, pk_slot_name) for v in input_object - } + return {v.get(pk_slot_name): _remove_pk(v, pk_slot_name) for v in input_object} elif isinstance(input_object, dict): if pk_slot_name and any( - v - for k, v in input_object.items() - if isinstance(v, dict) and v.get(pk_slot_name, None) is not None + v for k, v in input_object.items() if isinstance(v, dict) and v.get(pk_slot_name, None) is not None ): report.add_collection_form_normalization( ConstraintType.DictCollectionFormConstraint, @@ -691,9 +667,7 @@ def ensure_simple_dict( ) -> Any: simple_dict_value_slot = self._slot_as_simple_dict_value_slot(parent_slot) if not simple_dict_value_slot: - raise AssertionError( - f"Should have simple dict slot valie: {parent_slot.name}" - ) + raise AssertionError(f"Should have simple dict slot value: {parent_slot.name}") normalized_object = input_object if isinstance(input_object, list): normalized_object = {v[pk_slot_name]: v for v in input_object} @@ -725,9 +699,7 @@ def ensure_simple_dict( ) return normalized_object - def normalize_instance( - self, input_object: Any, parent_slot: SlotDefinition, report: Report - ) -> Any: + def normalize_instance(self, input_object: Any, parent_slot: SlotDefinition, report: Report) -> Any: range_element = self._slot_range_element(parent_slot) if input_object is None: return None @@ -752,43 +724,27 @@ def normalize_instance( else: return input_object - def normalize_reference( - self, input_object: dict, target: ClassDefinition, report: Report - ) -> dict: + def normalize_reference(self, input_object: dict, target: ClassDefinition, report: Report) -> dict: pk_slot = self._identifier_slot(target) if pk_slot is None: raise AssertionError(f"Cannot normalize: no primary key for {target.name}") - return self.normalize_type( - input_object, self.derived_schema.types.get(pk_slot.range, None), report - ) + return self.normalize_type(input_object, self.derived_schema.types.get(pk_slot.range, None), report) - def normalize_object( - self, input_object: dict, target: ClassDefinition, report: Report - ) -> dict: + def normalize_object(self, input_object: dict, target: ClassDefinition, report: Report) -> dict: if not isinstance(input_object, dict): - raise AssertionError( - f"Cannot normalize: expected dict, got {type(input_object)} for {input_object}" - ) + raise AssertionError(f"Cannot normalize: expected dict, got {type(input_object)} for {input_object}") output_object = {} # Induced slot for slot in target.attributes.values(): # TODO: required slots MUST be present UNLESS this is a CompactDict - if ( - slot.required - and slot.alias not in input_object - and not (slot.identifier or slot.key) - ): + if slot.required and slot.alias not in input_object and not (slot.identifier or slot.key): report.add_problem( ConstraintType.RequiredConstraint, slot.name, input_object, predicate=target.name, ) - if ( - slot.recommended - and slot.alias not in input_object - and not (slot.identifier or slot.key) - ): + if slot.recommended and slot.alias not in input_object and not (slot.identifier or slot.key): report.add_problem( ConstraintType.RecommendedConstraint, slot.name, @@ -796,9 +752,7 @@ def normalize_object( predicate=target.name, ) if slot.designates_type and slot.name in input_object: - induced_class_name = self._class_name_from_value( - input_object[slot.name], slot.range - ) + induced_class_name = self._class_name_from_value(input_object[slot.name], slot.range) new_target = self.derived_schema.classes[induced_class_name] if not self.subsumes(target, new_target): report.add_problem( @@ -837,20 +791,14 @@ def normalize_object( slot = target.attributes[actual_k] output_object[k] = self.normalize_slot_value(v, slot, report) if not self._matches_slot_expression(output_object[k], slot, output_object): - report.add_problem( - ConstraintType.ExpressionConstraint, target.name, output_object[k] - ) + report.add_problem(ConstraintType.ExpressionConstraint, target.name, output_object[k]) for rule in target.rules: self.evaluate_rule(output_object, rule, report) return output_object - def normalize_enum( - self, input_object: Any, target: EnumDefinition, report: Report - ) -> Any: + def normalize_enum(self, input_object: Any, target: EnumDefinition, report: Report) -> Any: if input_object not in target.permissible_values: - report.add_problem( - ConstraintType.PermissibleValueConstraint, target.name, input_object - ) + report.add_problem(ConstraintType.PermissibleValueConstraint, target.name, input_object) return input_object def normalize_type( @@ -863,16 +811,14 @@ def normalize_type( if input_object is None: return None if target is None: - return input_object + return input_object output_value = input_object if target.base in XSD_OR_BASE_TO_PYTHON: expected_python_type = XSD_OR_BASE_TO_PYTHON[target.base] elif target.uri in XSD_OR_BASE_TO_PYTHON: expected_python_type = XSD_OR_BASE_TO_PYTHON[target.uri] else: - report.add_problem( - ConstraintType.UnmappedTypeConstraint, target.name, input_object - ) + report.add_problem(ConstraintType.UnmappedTypeConstraint, target.name, input_object) return output_value current_python_type = type(input_object) if isinstance(expected_python_type, tuple): @@ -900,9 +846,7 @@ def normalize_type( output_value = normalize_func(input_object) if cast_func is not None: output_value = cast_func(output_value) - report.add_type_normalization( - current_python_type.__name__, expected_python_types[0].__name__ - ) + report.add_type_normalization(current_python_type.__name__, expected_python_types[0].__name__) except (ValueError, decimal.InvalidOperation) as e: problem = ValidationResult( ConstraintType.TypeConstraint, @@ -913,51 +857,29 @@ def normalize_type( report.results.append(problem) # validation if parent_slot: - if ( - parent_slot.maximum_value is not None - and output_value > parent_slot.maximum_value - ): - report.add_problem( - ConstraintType.MaximumValueConstraint, target.name, input_object - ) - if ( - parent_slot.minimum_value is not None - and output_value < parent_slot.minimum_value - ): - report.add_problem( - ConstraintType.MinimumValueConstraint, target.name, input_object - ) + if parent_slot.maximum_value is not None and output_value > parent_slot.maximum_value: + report.add_problem(ConstraintType.MaximumValueConstraint, target.name, input_object) + if parent_slot.minimum_value is not None and output_value < parent_slot.minimum_value: + report.add_problem(ConstraintType.MinimumValueConstraint, target.name, input_object) if parent_slot.pattern is not None: if not re.match(parent_slot.pattern, output_value): - report.add_problem( - ConstraintType.PatternConstraint, target.name, input_object - ) + report.add_problem(ConstraintType.PatternConstraint, target.name, input_object) if parent_slot.equals_string is not None: if output_value != parent_slot.equals_string: - report.add_problem( - ConstraintType.ExpressionConstraint, target.name, input_object - ) + report.add_problem(ConstraintType.ExpressionConstraint, target.name, input_object) return output_value - def evaluate_rule( - self, input_object: dict, rule: ClassRule, report: Report - ) -> None: + def evaluate_rule(self, input_object: dict, rule: ClassRule, report: Report) -> None: for cond in rule.preconditions: - if not self._matches_class_expression( - input_object.get(cond.slot, None), cond, input_object - ): + if not self._matches_class_expression(input_object.get(cond.slot, None), cond, input_object): return for cond in rule.postconditions: - if not self._matches_class_expression( - input_object.get(cond.slot, None), cond, input_object - ): + if not self._matches_class_expression(input_object.get(cond.slot, None), cond, input_object): report.add_problem(ConstraintType.RuleViolation, rule.name) return def subsumes(self, parent: ClassDefinition, child: ClassDefinition): - return parent.name in self.schemaview.class_ancestors( - child.name, reflexive=True - ) + return parent.name in self.schemaview.class_ancestors(child.name, reflexive=True) def _slot_range_element(self, slot: SlotDefinition) -> Optional[Element]: ds = self.derived_schema @@ -997,24 +919,16 @@ def _slot_inlined_as_compact_dict(self, slot: SlotDefinition) -> bool: # TODO: make this configurable return True - def _slot_as_simple_dict_value_slot( - self, slot: SlotDefinition - ) -> Optional[SlotDefinition]: + def _slot_as_simple_dict_value_slot(self, slot: SlotDefinition) -> Optional[SlotDefinition]: if not slot.inlined or slot.inlined_as_list: return False range_element = self._slot_range_element(slot) if isinstance(range_element, ClassDefinition): - non_pk_atts = [ - s - for s in range_element.attributes.values() - if not s.identifier and not s.key - ] + non_pk_atts = [s for s in range_element.attributes.values() if not s.identifier and not s.key] if len(non_pk_atts) == 1: return non_pk_atts[0] - def _identifier_slot_name( - self, cls: ClassDefinition - ) -> Optional[SlotDefinitionName]: + def _identifier_slot_name(self, cls: ClassDefinition) -> Optional[SlotDefinitionName]: for slot in cls.attributes.values(): if slot.identifier: return slot.name @@ -1043,9 +957,7 @@ def _matches_class_expression( expr: AnonymousClassExpression, ) -> bool: if expr.is_a: - if expr.is_a not in self.schemaview.class_ancestors( - target.name, reflexive=True - ): + if expr.is_a not in self.schemaview.class_ancestors(target.name, reflexive=True): return False for slot_name, slot_expression in expr.slot_conditions.items(): v = input_object.get(slot_name, None) @@ -1063,19 +975,11 @@ def _matches_slot_expression( if self._matches_slot_expression(slot_value, x, input_object): return False if expr.exactly_one_of: - vals = [ - x - for x in expr.exactly_one_of - if self._matches_slot_expression(slot_value, x, input_object) - ] + vals = [x for x in expr.exactly_one_of if self._matches_slot_expression(slot_value, x, input_object)] if len(vals) != 1: return False if expr.any_of: - vals = [ - x - for x in expr.any_of - if self._matches_slot_expression(slot_value, x, input_object) - ] + vals = [x for x in expr.any_of if self._matches_slot_expression(slot_value, x, input_object)] if not vals: return False for x in expr.all_of: @@ -1094,16 +998,13 @@ def _matches_slot_expression( @click.command -@click.option("--schema", "-s", required=True, - help="Path to LinkML schema") -@click.option("--target", "-C", - help="name of target class or element to normalize/validate against") -@click.option("--report-file", "-R", type=click.File("w"), default=sys.stderr, - show_default=True, - help="path to file for reports") +@click.option("--schema", "-s", required=True, help="Path to LinkML schema") +@click.option("--target", "-C", help="name of target class or element to normalize/validate against") +@click.option( + "--report-file", "-R", type=click.File("w"), default=sys.stderr, show_default=True, help="path to file for reports" +) @click.option("--output", "-o", type=click.File("w"), default=sys.stdout) -@click.option("--expand-all/--no-expand-all", - help="If True, expand all Dicts to ExpandedDicts") +@click.option("--expand-all/--no-expand-all", help="If True, expand all Dicts to ExpandedDicts") @click.argument("input") def cli(schema: str, target: str, input: str, report_file: TextIO, output: TextIO, **kwargs) -> None: """ diff --git a/linkml_runtime/processing/validation_datamodel.py b/linkml_runtime/processing/validation_datamodel.py index a6d83876..3808243c 100644 --- a/linkml_runtime/processing/validation_datamodel.py +++ b/linkml_runtime/processing/validation_datamodel.py @@ -6,23 +6,23 @@ # description: A datamodel for data validation results. # license: https://creativecommons.org/publicdomain/zero/1.0/ -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union + +from jsonasobj2 import as_dict +from rdflib import URIRef + from linkml_runtime.linkml_model.meta import ( EnumDefinition, PermissibleValue, ) - +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import Bool, URIorCURIE, empty_dict, empty_list from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict from linkml_runtime.utils.yamlutils import ( YAMLRoot, ) -from linkml_runtime.utils.enumerations import EnumDefinitionImpl -from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import Bool, URIorCURIE metamodel_version = "1.7.0" version = None @@ -43,6 +43,7 @@ # Types + # Class references class ConstraintCheckId(URIorCURIE): pass @@ -121,9 +122,7 @@ class ValidationConfiguration(YAMLRoot): ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): - if self.max_number_results_per_type is not None and not isinstance( - self.max_number_results_per_type, int - ): + if self.max_number_results_per_type is not None and not isinstance(self.max_number_results_per_type, int): self.max_number_results_per_type = int(self.max_number_results_per_type) self._normalize_inlined_as_dict( @@ -156,9 +155,7 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.validation_configuration is not None and not isinstance( self.validation_configuration, ValidationConfiguration ): - self.validation_configuration = ValidationConfiguration( - **as_dict(self.validation_configuration) - ) + self.validation_configuration = ValidationConfiguration(**as_dict(self.validation_configuration)) if self.dry_run is not None and not isinstance(self.dry_run, Bool): self.dry_run = Bool(self.dry_run) @@ -207,16 +204,12 @@ class Report(YAMLRoot): class_name: ClassVar[str] = "Report" class_model_uri: ClassVar[URIRef] = VM.Report - results: Optional[ - Union[Union[dict, "Result"], list[Union[dict, "Result"]]] - ] = empty_list() + results: Optional[Union[Union[dict, "Result"], list[Union[dict, "Result"]]]] = empty_list() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.results, list): self.results = [self.results] if self.results is not None else [] - self.results = [ - v if isinstance(v, Result) else Result(**as_dict(v)) for v in self.results - ] + self.results = [v if isinstance(v, Result) else Result(**as_dict(v)) for v in self.results] super().__post_init__(**kwargs) @@ -234,17 +227,12 @@ class ValidationReport(Report): class_name: ClassVar[str] = "ValidationReport" class_model_uri: ClassVar[URIRef] = VM.ValidationReport - results: Optional[ - Union[Union[dict, "ValidationResult"], list[Union[dict, "ValidationResult"]]] - ] = empty_list() + results: Optional[Union[Union[dict, "ValidationResult"], list[Union[dict, "ValidationResult"]]]] = empty_list() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.results, list): self.results = [self.results] if self.results is not None else [] - self.results = [ - v if isinstance(v, ValidationResult) else ValidationResult(**as_dict(v)) - for v in self.results - ] + self.results = [v if isinstance(v, ValidationResult) else ValidationResult(**as_dict(v)) for v in self.results] super().__post_init__(**kwargs) @@ -262,17 +250,12 @@ class RepairReport(Report): class_name: ClassVar[str] = "RepairReport" class_model_uri: ClassVar[URIRef] = VM.RepairReport - results: Optional[ - Union[Union[dict, "RepairOperation"], list[Union[dict, "RepairOperation"]]] - ] = empty_list() + results: Optional[Union[Union[dict, "RepairOperation"], list[Union[dict, "RepairOperation"]]]] = empty_list() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.results, list): self.results = [self.results] if self.results is not None else [] - self.results = [ - v if isinstance(v, RepairOperation) else RepairOperation(**as_dict(v)) - for v in self.results - ] + self.results = [v if isinstance(v, RepairOperation) else RepairOperation(**as_dict(v)) for v in self.results] super().__post_init__(**kwargs) @@ -354,19 +337,13 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.repaired is not None and not isinstance(self.repaired, Bool): self.repaired = Bool(self.repaired) - if self.source_line_number is not None and not isinstance( - self.source_line_number, int - ): + if self.source_line_number is not None and not isinstance(self.source_line_number, int): self.source_line_number = int(self.source_line_number) - if self.source_column_number is not None and not isinstance( - self.source_column_number, int - ): + if self.source_column_number is not None and not isinstance(self.source_column_number, int): self.source_column_number = int(self.source_column_number) - if self.source_location is not None and not isinstance( - self.source_location, str - ): + if self.source_location is not None and not isinstance(self.source_location, str): self.source_location = str(self.source_location) super().__post_init__(**kwargs) @@ -428,7 +405,8 @@ class ConstraintType(EnumDefinitionImpl): ) MinCountConstraint = PermissibleValue( text="MinCountConstraint", - description="cardinality constraint where the number of values of the slot must be greater or equal to a specified minimum", + description="cardinality constraint where the number of values of the slot must be greater than " + "or equal to a specified minimum", meaning=SH.MinCountConstraintComponent, ) RequiredConstraint = PermissibleValue( @@ -443,7 +421,8 @@ class ConstraintType(EnumDefinitionImpl): ) MaxCountConstraint = PermissibleValue( text="MaxCountConstraint", - description="cardinality constraint where the number of values of the slot must be less than or equal to a specified maximum", + description="cardinality constraint where the number of values of the slot must be less than " + "or equal to a specified maximum", meaning=SH.MaxCountConstraintComponent, ) SingleValuedConstraint = PermissibleValue( @@ -480,12 +459,8 @@ class ConstraintType(EnumDefinitionImpl): meaning=SH.ClosedConstraintComponent, ) DesignatesTypeConstraint = PermissibleValue(text="DesignatesTypeConstraint") - InstanceConstraint = PermissibleValue( - text="InstanceConstraint", meaning=SH.NodeConstraintComponent - ) - SlotConstraint = PermissibleValue( - text="SlotConstraint", meaning=SH.PropertyConstraintComponent - ) + InstanceConstraint = PermissibleValue(text="InstanceConstraint", meaning=SH.NodeConstraintComponent) + SlotConstraint = PermissibleValue(text="SlotConstraint", meaning=SH.PropertyConstraintComponent) PermissibleValueConstraint = PermissibleValue( text="PermissibleValueConstraint", description="constraint where the slot value must be one of a set of permissible values", @@ -507,15 +482,9 @@ class ConstraintType(EnumDefinitionImpl): text="LessThanOrEqualsExpressionConstraint", meaning=SH.LessThanOrEqualsComponent, ) - DisjointConstraint = PermissibleValue( - text="DisjointConstraint", meaning=SH.DisjointConstraintComponent - ) - MinimumValueConstraint = PermissibleValue( - text="MinimumValueConstraint", meaning=SH.MinInclusiveConstraintComponent - ) - MaximumValueConstraint = PermissibleValue( - text="MaximumValueConstraint", meaning=SH.MaxInclusiveConstraintComponent - ) + DisjointConstraint = PermissibleValue(text="DisjointConstraint", meaning=SH.DisjointConstraintComponent) + MinimumValueConstraint = PermissibleValue(text="MinimumValueConstraint", meaning=SH.MinInclusiveConstraintComponent) + MaximumValueConstraint = PermissibleValue(text="MaximumValueConstraint", meaning=SH.MaxInclusiveConstraintComponent) MinimumExclusiveValueConstraint = PermissibleValue( text="MinimumExclusiveValueConstraint", meaning=SH.MinExclusiveInclusiveConstraintComponent, @@ -527,15 +496,9 @@ class ConstraintType(EnumDefinitionImpl): CollectionFormConstraint = PermissibleValue(text="CollectionFormConstraint") ListCollectionFormConstraint = PermissibleValue(text="ListCollectionFormConstraint") DictCollectionFormConstraint = PermissibleValue(text="DictCollectionFormConstraint") - SimpleDictCollectionFormConstraint = PermissibleValue( - text="SimpleDictCollectionFormConstraint" - ) - CompactDictCollectionFormConstraint = PermissibleValue( - text="CompactDictCollectionFormConstraint" - ) - ExpandedDictCollectionFormConstraint = PermissibleValue( - text="ExpandedDictCollectionFormConstraint" - ) + SimpleDictCollectionFormConstraint = PermissibleValue(text="SimpleDictCollectionFormConstraint") + CompactDictCollectionFormConstraint = PermissibleValue(text="CompactDictCollectionFormConstraint") + ExpandedDictCollectionFormConstraint = PermissibleValue(text="ExpandedDictCollectionFormConstraint") _defn = EnumDefinition( name="ConstraintType", @@ -717,9 +680,7 @@ class slots: domain=None, range=Optional[ Union[ - dict[ - Union[str, TypeSeverityKeyValueType], Union[dict, TypeSeverityKeyValue] - ], + dict[Union[str, TypeSeverityKeyValueType], Union[dict, TypeSeverityKeyValue]], list[Union[dict, TypeSeverityKeyValue]], ] ], @@ -803,9 +764,7 @@ class slots: curie=SH.curie("result"), model_uri=VM.ValidationReport_results, domain=ValidationReport, - range=Optional[ - Union[Union[dict, "ValidationResult"], list[Union[dict, "ValidationResult"]]] - ], + range=Optional[Union[Union[dict, "ValidationResult"], list[Union[dict, "ValidationResult"]]]], ) slots.RepairReport_results = Slot( @@ -814,7 +773,5 @@ class slots: curie=SH.curie("result"), model_uri=VM.RepairReport_results, domain=RepairReport, - range=Optional[ - Union[Union[dict, "RepairOperation"], list[Union[dict, "RepairOperation"]]] - ], + range=Optional[Union[Union[dict, "RepairOperation"], list[Union[dict, "RepairOperation"]]]], ) diff --git a/linkml_runtime/utils/comparefiles.py b/linkml_runtime/utils/comparefiles.py index 7c3bd3dd..0b5ed47a 100644 --- a/linkml_runtime/utils/comparefiles.py +++ b/linkml_runtime/utils/comparefiles.py @@ -4,9 +4,9 @@ import click -def compare_files(file: str, target: str, comments: str = r'^\s+#.*\n') -> int: +def compare_files(file: str, target: str, comments: str = r"^\s+#.*\n") -> int: def filtr(txt: str) -> str: - return re.sub(comments, '', txt, flags=re.MULTILINE).strip() + return re.sub(comments, "", txt, flags=re.MULTILINE).strip() with open(target) as oldfile: oldtext = filtr(oldfile.read()) @@ -21,9 +21,9 @@ def filtr(txt: str) -> str: @click.argument("file2", type=click.Path(exists=True, dir_okay=False)) @click.option("-c", "--comments", help="Comments regexp", default="^#.*$", show_default=True) def cli(file1, file2, comments) -> None: - """ Compare file1 to file2 using a filter """ + """Compare file1 to file2 using a filter""" sys.exit(compare_files(file1, file2, comments)) -if __name__ == '__main__': +if __name__ == "__main__": cli(sys.argv[1:]) diff --git a/linkml_runtime/utils/compile_python.py b/linkml_runtime/utils/compile_python.py index 7afea08d..85556b0c 100644 --- a/linkml_runtime/utils/compile_python.py +++ b/linkml_runtime/utils/compile_python.py @@ -10,7 +10,7 @@ def file_text(txt_or_fname: str) -> str: :param txt_or_fname: :return: """ - if len(txt_or_fname) > 4 and '\n' not in txt_or_fname: + if len(txt_or_fname) > 4 and "\n" not in txt_or_fname: with open(txt_or_fname) as ef: return ef.read() return txt_or_fname @@ -27,8 +27,8 @@ def compile_python(text_or_fn: str, package_path: str = None) -> ModuleType: python_txt = file_text(text_or_fn) if package_path is None and python_txt != text_or_fn: package_path = text_or_fn - spec = compile(python_txt, 'test', 'exec') - module = ModuleType('test') + spec = compile(python_txt, "test", "exec") + module = ModuleType("test") if package_path: package_path_abs = os.path.join(os.getcwd(), package_path) # We have to calculate the path to expected path relative to the current working directory @@ -41,8 +41,10 @@ def compile_python(text_or_fn: str, package_path: str = None) -> ModuleType: break else: warning(f"There is no established path to {package_path} - compile_python may or may not work") - path_from_tests_parent = os.path.relpath(package_path, os.path.join(os.getcwd(), '..')) - module.__package__ = os.path.dirname(os.path.relpath(path_from_tests_parent, os.getcwd())).replace(os.path.sep, '.') + path_from_tests_parent = os.path.relpath(package_path, os.path.join(os.getcwd(), "..")) + module.__package__ = os.path.dirname(os.path.relpath(path_from_tests_parent, os.getcwd())).replace( + os.path.sep, "." + ) sys.modules[module.__name__] = module exec(spec, module.__dict__) return module diff --git a/linkml_runtime/utils/context_utils.py b/linkml_runtime/utils/context_utils.py index 922aaaf5..376fd59a 100644 --- a/linkml_runtime/utils/context_utils.py +++ b/linkml_runtime/utils/context_utils.py @@ -1,17 +1,20 @@ import json import os from io import TextIOWrapper -from typing import Optional, Union, Any, Callable +from typing import TYPE_CHECKING, Any, Callable, Optional, Union import yaml from jsonasobj2 import JsonObj, loads +if TYPE_CHECKING: + from linkml_runtime.utils.namespaces import Namespaces + CONTEXT_TYPE = Union[str, dict, JsonObj] CONTEXTS_PARAM_TYPE = Optional[Union[CONTEXT_TYPE, list[CONTEXT_TYPE]]] def merge_contexts(contexts: CONTEXTS_PARAM_TYPE = None, base: Optional[Any] = None) -> JsonObj: - """ Take a list of JSON-LD contexts, which can be one of: + """Take a list of JSON-LD contexts, which can be one of: * the name of a JSON-LD file * the URI of a JSON-lD file * JSON-LD text @@ -27,11 +30,12 @@ def merge_contexts(contexts: CONTEXTS_PARAM_TYPE = None, base: Optional[Any] = N :param base: base to add in (optional) :return: aggregated context """ + def prune_context_node(ctxt: Union[str, JsonObj]) -> Union[str, JsonObj]: - return ctxt['@context'] if isinstance(ctxt, JsonObj) and '@context' in ctxt else ctxt + return ctxt["@context"] if isinstance(ctxt, JsonObj) and "@context" in ctxt else ctxt def to_file_uri(fname: str) -> str: - return 'file://' + fname + return "file://" + fname context_list = [] for context in [] if contexts is None else [contexts] if not isinstance(contexts, (list, tuple, set)) else contexts: @@ -39,15 +43,18 @@ def to_file_uri(fname: str) -> str: # One of filename, URL or json text if context.strip().startswith("{"): context = loads(context) - elif '://' not in context: + elif "://" not in context: context = to_file_uri(context) elif not isinstance(context, (JsonObj, str)): - context = JsonObj(**context) # dict + context = JsonObj(**context) # dict context_list.append(prune_context_node(context)) if base: - context_list.append(JsonObj(**{'@base': str(base)})) - return None if not context_list else \ - JsonObj(**{"@context": context_list[0] if len(context_list) == 1 else context_list}) + context_list.append(JsonObj(**{"@base": str(base)})) + return ( + None + if not context_list + else JsonObj(**{"@context": context_list[0] if len(context_list) == 1 else context_list}) + ) def map_import(importmap: dict[str, str], namespaces: Callable[[None], "Namespaces"], imp: Any) -> str: @@ -62,10 +69,10 @@ def map_import(importmap: dict[str, str], namespaces: Callable[[None], "Namespac :return: """ sname = str(imp) - if ':' in sname: + if ":" in sname: # the importmap may contain mappings for prefixes - prefix, lname = sname.split(':', 1) - prefix += ':' + prefix, lname = sname.split(":", 1) + prefix += ":" expanded_prefix = importmap.get(prefix) if expanded_prefix is not None: if expanded_prefix.startswith("http"): @@ -73,12 +80,13 @@ def map_import(importmap: dict[str, str], namespaces: Callable[[None], "Namespac else: sname = os.path.join(expanded_prefix, lname) sname = importmap.get(sname, sname) # Import map may use CURIE - sname = str(namespaces().uri_for(sname)) if ':' in sname else sname + sname = str(namespaces().uri_for(sname)) if ":" in sname else sname return importmap.get(sname, sname) # It may also use URI or other forms -def parse_import_map(map_: Optional[Union[str, dict[str, str], TextIOWrapper]], - base: Optional[str] = None) -> dict[str, str]: +def parse_import_map( + map_: Optional[Union[str, dict[str, str], TextIOWrapper]], base: Optional[str] = None +) -> dict[str, str]: """ Process the import map :param map_: A map location, the JSON for a map, YAML for a map or an existing dictionary @@ -92,9 +100,9 @@ def parse_import_map(map_: Optional[Union[str, dict[str, str], TextIOWrapper]], return parse_import_map(map_.read(), base) elif isinstance(map_, dict): rval = map_ - elif map_.strip().startswith('{'): + elif map_.strip().startswith("{"): rval = json.loads(map_) - elif '\n' in map_ or '\r' in map_ or ' ' in map_: + elif "\n" in map_ or "\r" in map_ or " " in map_: rval = yaml.safe_load(map_) else: with open(map_) as ml: @@ -103,7 +111,7 @@ def parse_import_map(map_: Optional[Union[str, dict[str, str], TextIOWrapper]], if base: outmap = dict() for k, v in rval.items(): - if ':' not in v: + if ":" not in v: v = os.path.join(os.path.abspath(base), v) outmap[k] = v rval = outmap diff --git a/linkml_runtime/utils/csvutils.py b/linkml_runtime/utils/csvutils.py index 7813f078..9a5455a1 100644 --- a/linkml_runtime/utils/csvutils.py +++ b/linkml_runtime/utils/csvutils.py @@ -1,7 +1,9 @@ import logging + from json_flattener import KeyConfig, Serializer from json_flattener.flattener import CONFIGMAP -from linkml_runtime.linkml_model.meta import SlotDefinitionName, ClassDefinitionName + +from linkml_runtime.linkml_model.meta import ClassDefinitionName, SlotDefinitionName from linkml_runtime.utils.schemaview import SchemaView logger = logging.getLogger(__name__) @@ -30,12 +32,13 @@ def get_configmap(schemaview: SchemaView, index_slot: SlotDefinitionName) -> CON cm[sn] = config return cm else: - logger.warning(f'Index slot range not to class: {slot.range}') + logger.warning(f"Index slot range not to class: {slot.range}") else: - logger.warning(f'Index slot or schema not specified') + logger.warning("Index slot or schema not specified") return {} -def _get_key_config(schemaview: SchemaView, tgt_cls: ClassDefinitionName, sn: SlotDefinitionName, sep='_'): + +def _get_key_config(schemaview: SchemaView, tgt_cls: ClassDefinitionName, sn: SlotDefinitionName, sep="_"): slot = schemaview.induced_slot(sn, tgt_cls) range = slot.range all_cls = schemaview.all_classes() @@ -43,7 +46,7 @@ def _get_key_config(schemaview: SchemaView, tgt_cls: ClassDefinitionName, sn: Sl mappings = {} is_complex = False for inner_sn in schemaview.class_slots(range): - denormalized_sn = f'{sn}{sep}{inner_sn}' + denormalized_sn = f"{sn}{sep}{inner_sn}" mappings[inner_sn] = denormalized_sn inner_slot = schemaview.induced_slot(inner_sn, range) inner_slot_range = inner_slot.range @@ -53,6 +56,8 @@ def _get_key_config(schemaview: SchemaView, tgt_cls: ClassDefinitionName, sn: Sl serializers = [Serializer.json] else: serializers = [] - return KeyConfig(is_list=slot.multivalued, delete=True, flatten=True, mappings=mappings, serializers=serializers) + return KeyConfig( + is_list=slot.multivalued, delete=True, flatten=True, mappings=mappings, serializers=serializers + ) else: return None diff --git a/linkml_runtime/utils/curienamespace.py b/linkml_runtime/utils/curienamespace.py index fc342daa..b241c522 100644 --- a/linkml_runtime/utils/curienamespace.py +++ b/linkml_runtime/utils/curienamespace.py @@ -9,9 +9,9 @@ def __new__(cls, prefix: str, value: Union[str, URIRef]): try: rt = str.__new__(cls, value) except UnicodeDecodeError: - rt = str.__new__(cls, value, 'utf-8') + rt = str.__new__(cls, value, "utf-8") rt.prefix = prefix return rt - def curie(self, reference: Optional[str] = '') -> str: - return self.prefix + ':' + reference + def curie(self, reference: Optional[str] = "") -> str: + return self.prefix + ":" + reference diff --git a/linkml_runtime/utils/dataclass_extensions_376.py b/linkml_runtime/utils/dataclass_extensions_376.py index 4321855d..93cc1743 100644 --- a/linkml_runtime/utils/dataclass_extensions_376.py +++ b/linkml_runtime/utils/dataclass_extensions_376.py @@ -1,6 +1,5 @@ -import sys -import warnings import dataclasses +import warnings warnings.warn( "The LinkML dataclass extension patch is deprecated and will be removed in a future release.\n" @@ -8,8 +7,8 @@ " • Upgrade your LinkML tooling to version >= 1.9.0 (which no longer needs this patch), OR\n" " • Migrate to Pydantic models if you're using LinkML's generated classes at runtime.\n", DeprecationWarning, - stacklevel=2 + stacklevel=2, ) dataclasses_init_fn_with_kwargs = dataclasses._init_fn -DC_CREATE_FN = False \ No newline at end of file +DC_CREATE_FN = False diff --git a/linkml_runtime/utils/dictutils.py b/linkml_runtime/utils/dictutils.py index 06763832..50424694 100644 --- a/linkml_runtime/utils/dictutils.py +++ b/linkml_runtime/utils/dictutils.py @@ -3,6 +3,7 @@ from linkml_runtime.dumpers import json_dumper from linkml_runtime.utils.yamlutils import YAMLRoot + def as_simple_dict(element: YAMLRoot) -> dict: """ Returns the representation of element as a python dictionary diff --git a/linkml_runtime/utils/distroutils.py b/linkml_runtime/utils/distroutils.py index 60e7ce90..5749e6fb 100644 --- a/linkml_runtime/utils/distroutils.py +++ b/linkml_runtime/utils/distroutils.py @@ -1,6 +1,7 @@ """ Packaging for working with LinkML distributions """ + import logging import pkgutil from pathlib import PurePath @@ -18,33 +19,35 @@ def get_default_paths(file_type: str) -> list[PurePath]: paths = [] rel_dirs = [] # TODO: introspect this information - srcp = PurePath('src') - if file_type == 'yaml': - rel_dirs = [PurePath('model') /'schema', - PurePath('schema'), - PurePath('linkml'), - srcp / 'linkml', - srcp / 'model', - srcp / 'model' / 'schema', - srcp / 'schema', - ] - elif file_type == 'schema.json': - rel_dirs = [PurePath('jsonschema')] - elif file_type == 'context.jsonld': - rel_dirs = [PurePath('jsonld')] - elif '.' in file_type: + srcp = PurePath("src") + if file_type == "yaml": + rel_dirs = [ + PurePath("model") / "schema", + PurePath("schema"), + PurePath("linkml"), + srcp / "linkml", + srcp / "model", + srcp / "model" / "schema", + srcp / "schema", + ] + elif file_type == "schema.json": + rel_dirs = [PurePath("jsonschema")] + elif file_type == "context.jsonld": + rel_dirs = [PurePath("jsonld")] + elif "." in file_type: # e.g. 'owl.ttl' --> 'owl' - rel_dirs = [PurePath(file_type.split('.')[0])] + rel_dirs = [PurePath(file_type.split(".")[0])] else: rel_dirs = [] for rel_dir in rel_dirs: paths.append(rel_dir) # YAML files may be in the same directory as the python - paths.append(PurePath('.')) + paths.append(PurePath(".")) logger.debug(f"Paths to search: {paths}") return paths -def get_packaged_file_as_str(package: str, file_type: str, rel_paths: list[PurePath]=[], encoding="utf-8") -> str: + +def get_packaged_file_as_str(package: str, file_type: str, rel_paths: list[PurePath] = [], encoding="utf-8") -> str: """ Retrieve the value of a data file distributed alongside a python package @@ -54,24 +57,26 @@ def get_packaged_file_as_str(package: str, file_type: str, rel_paths: list[PureP :param encoding: :return: """ - parts = package.split('.') + parts = package.split(".") package_name = parts[-1] suffix = file_type data = None for path in get_default_paths(file_type) + rel_paths: try: - full_path = path / f'{package_name}.{suffix}' + full_path = path / f"{package_name}.{suffix}" data = pkgutil.get_data(package, str(full_path)) if data: break except FileNotFoundError: - logger.debug(f'candidate {path} not found') + logger.debug(f"candidate {path} not found") if not data: - raise FileNotFoundError(f'package: {package} file: {file_type}') + raise FileNotFoundError(f"package: {package} file: {file_type}") return data.decode(encoding) + def get_schema_string(package: str, **kwargs) -> str: - return get_packaged_file_as_str(package, file_type='yaml', **kwargs) + return get_packaged_file_as_str(package, file_type="yaml", **kwargs) + def get_jsonschema_string(package: str, **kwargs) -> str: - return get_packaged_file_as_str(package, file_type='schema.json', **kwargs) + return get_packaged_file_as_str(package, file_type="schema.json", **kwargs) diff --git a/linkml_runtime/utils/enumerations.py b/linkml_runtime/utils/enumerations.py index 6b9cd047..84a3ca48 100644 --- a/linkml_runtime/utils/enumerations.py +++ b/linkml_runtime/utils/enumerations.py @@ -1,9 +1,12 @@ from dataclasses import fields -from typing import Union, Optional +from typing import TYPE_CHECKING, Optional, Union from linkml_runtime.utils.metamodelcore import Curie from linkml_runtime.utils.yamlutils import YAMLRoot +if TYPE_CHECKING: + from linkml_runtime.linkml_model import EnumDefinition, PermissibleValue + class EnumDefinitionMeta(type): def __init__(cls, *args, **kwargs): @@ -20,6 +23,7 @@ def __setitem__(cls, key, value): def __setattr__(self, key, value): from linkml_runtime.linkml_model.meta import PermissibleValue + if self._defn.code_set and isinstance(value, PermissibleValue) and value.meaning: print(f"Validating {value.meaning} against {self._defn.code_set}") super().__setattr__(key, value) @@ -29,11 +33,12 @@ def __contains__(cls, item) -> bool: def isinstance_dt(cls: type, inst: str) -> bool: - """ Duck typing isinstance to prevent recursion errors """ + """Duck typing isinstance to prevent recursion errors""" return inst in [c.__name__ for c in type(cls).mro()] + class EnumDefinitionImpl(YAMLRoot, metaclass=EnumDefinitionMeta): - _defn: "EnumDefinition" = None # Overridden by implementation + _defn: "EnumDefinition" = None # Overridden by implementation def __init__(self, code: Union[str, Curie]) -> None: if isinstance_dt(code, "PermissibleValue"): @@ -51,10 +56,12 @@ def __init__(self, code: Union[str, Curie]) -> None: elif key not in self.__class__: raise ValueError(f"Unknown {self.__class__.__name__} enumeration code: {key}") elif isinstance_dt(code, "PermissibleValue"): - if getattr(self, 'code', None): + if getattr(self, "code", None): if self._code != code: - raise ValueError(f"Enumeration: {self.__class__.__name__} - " - f"Cannot change an existing permissible value entry for {code}") + raise ValueError( + f"Enumeration: {self.__class__.__name__} - " + f"Cannot change an existing permissible value entry for {code}" + ) else: self._code = code else: @@ -93,13 +100,13 @@ def curie(self): @classmethod def _addvals(cls): - """ Override this to add non-python compatible values """ + """Override this to add non-python compatible values""" pass def __str__(self) -> str: - """ The string representation of an enumerated value should be the code representing this value.""" + """The string representation of an enumerated value should be the code representing this value.""" return self._code.text def __repr__(self) -> str: rlist = [(f.name, getattr(self._code, f.name)) for f in fields(self._code)] - return self.__class__.__name__ + '(' + ', '.join([f"{f[0]}={repr(f[1])}" for f in rlist if f[1]]) + ')' + return self.__class__.__name__ + "(" + ", ".join([f"{f[0]}={repr(f[1])}" for f in rlist if f[1]]) + ")" diff --git a/linkml_runtime/utils/eval_utils.py b/linkml_runtime/utils/eval_utils.py index 86b02c8e..dc4c21ab 100644 --- a/linkml_runtime/utils/eval_utils.py +++ b/linkml_runtime/utils/eval_utils.py @@ -8,16 +8,23 @@ import operator as op # supported operators -from typing import Any - -operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, - ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor, - ast.USub: op.neg} +from typing import Any, Callable + +operators = { + ast.Add: op.add, + ast.Sub: op.sub, + ast.Mult: op.mul, + ast.Div: op.truediv, + ast.Pow: op.pow, + ast.BitXor: op.xor, + ast.USub: op.neg, +} compare_operators = {ast.Eq: op.eq, ast.Lt: op.lt, ast.LtE: op.le, ast.Gt: op.gt, ast.GtE: op.ge} + def eval_conditional(*conds: list[tuple[bool, Any]]) -> Any: """ - Evaluate a collection of expression,value tuples, returing the first value whose expression is true + Evaluate a collection of expression, value tuples, returning the first value whose expression is true >>> x= 40 >>> eval_conditional((x < 25, 'low'), (x > 25, 'high'), (True, 'low')) @@ -31,13 +38,14 @@ def eval_conditional(*conds: list[tuple[bool, Any]]) -> Any: return val -# (takes_list, func) -funcs = {'max': (True, max), - 'min': (True, min), - 'len': (True, len), - 'str': (False, str), - 'strlen': (False, len), - 'case': (False, eval_conditional)} +funcs: dict[str, tuple[bool, Callable]] = { + "max": (True, max), + "min": (True, min), + "len": (True, len), + "str": (False, str), + "strlen": (False, len), + "case": (False, eval_conditional), +} class UnsetValueException(Exception): @@ -87,26 +95,25 @@ def eval_expr(expr: str, _distribute=True, **kwargs) -> Any: :param kwargs: variables to substitute :return: result of evaluation """ - #if kwargs: + # if kwargs: # expr = expr.format(**kwargs) - if 'None' in expr: + if "None" in expr: # TODO: do this as part of parsing return None else: try: - return eval_(ast.parse(expr, mode='eval').body, kwargs, distribute=_distribute) + return eval_(ast.parse(expr, mode="eval").body, kwargs, distribute=_distribute) except UnsetValueException: return None - def eval_(node, bindings=None, distribute=True): if bindings is None: bindings = {} if isinstance(node, ast.Num): return node.n elif isinstance(node, ast.Str): - if 's' in vars(node): + if "s" in vars(node): return node.s else: return node.value @@ -125,6 +132,7 @@ def eval_(node, bindings=None, distribute=True): elif isinstance(node, ast.Attribute): # e.g. for person.name, this returns the val of person v = eval_(node.value, bindings) + # lookup attribute, potentially distributing the results over collections def _get(obj: Any, k: str, recurse=distribute) -> Any: if isinstance(obj, dict): @@ -140,19 +148,20 @@ def _get(obj: Any, k: str, recurse=distribute) -> Any: return None else: return getattr(obj, k) + return _get(v, node.attr) elif isinstance(node, ast.List): return [eval_(x, bindings) for x in node.elts] elif isinstance(node, ast.Set): # sets are not part of the language; we use {x} as notation for x if len(node.elts) != 1: - raise ValueError(f'The {{}} must enclose a single variable') + raise ValueError("The {} must enclose a single variable") e = node.elts[0] if not isinstance(e, ast.Name): - raise ValueError(f'The {{}} must enclose a variable') + raise ValueError("The {} must enclose a variable") v = eval_(e, bindings) if v is None: - raise UnsetValueException(f'{e} is not set') + raise UnsetValueException(f"{e} is not set") else: return v elif isinstance(node, ast.Tuple): @@ -161,19 +170,19 @@ def _get(obj: Any, k: str, recurse=distribute) -> Any: return {eval_(k, bindings): eval_(v, bindings) for k, v in zip(node.keys, node.values)} elif isinstance(node, ast.Compare): # if len(node.ops) != 1: - raise ValueError(f'Must be exactly one op in {node}') + raise ValueError(f"Must be exactly one op in {node}") if type(node.ops[0]) not in compare_operators: - raise NotImplementedError(f'Not implemented: {node.ops[0]} in {node}') + raise NotImplementedError(f"Not implemented: {node.ops[0]} in {node}") py_op = compare_operators[type(node.ops[0])] if len(node.comparators) != 1: - raise ValueError(f'Must be exactly one comparator in {node}') + raise ValueError(f"Must be exactly one comparator in {node}") right = node.comparators[0] return py_op(eval_(node.left, bindings), eval_(right, bindings)) elif isinstance(node, ast.BinOp): # return operators[type(node.op)](eval_(node.left, bindings), eval_(node.right, bindings)) elif isinstance(node, ast.UnaryOp): # e.g., -1 return operators[type(node.op)](eval_(node.operand, bindings)) - #elif isinstance(node, ast.Match): + # elif isinstance(node, ast.Match): # # implementing this would restrict python version to 3.10 # # https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python # raise NotImplementedError(f'Not supported') @@ -189,9 +198,9 @@ def _get(obj: Any, k: str, recurse=distribute) -> Any: takes_list, func = funcs[fn] args = [eval_(x, bindings) for x in node.args] if isinstance(args[0], list) and not takes_list: - return [func(*[x]+args[1:]) for x in args[0]] + return [func(*[x] + args[1:]) for x in args[0]] else: return func(*args) - raise NotImplementedError(f'Call {node.func} not implemented. node = {node}') + raise NotImplementedError(f"Call {node.func} not implemented. node = {node}") else: raise TypeError(node) diff --git a/linkml_runtime/utils/formatutils.py b/linkml_runtime/utils/formatutils.py index 37e437d2..9efcd0a1 100644 --- a/linkml_runtime/utils/formatutils.py +++ b/linkml_runtime/utils/formatutils.py @@ -2,14 +2,14 @@ from decimal import Decimal from typing import Any -from jsonasobj2 import JsonObj, as_dict, is_list, is_dict, items +from jsonasobj2 import JsonObj, as_dict, is_dict, is_list, items -ws_pattern = re.compile(r'\s+') -us_pattern = re.compile(r'_+') +ws_pattern = re.compile(r"\s+") +us_pattern = re.compile(r"_+") def uncamelcase(txt: str) -> str: - split_txt = re.split('(?=[A-Z])', txt) + split_txt = re.split("(?=[A-Z])", txt) new_text = "" for word in split_txt: if new_text == "": @@ -21,13 +21,13 @@ def uncamelcase(txt: str) -> str: def camelcase(txt: str) -> str: def _up(s: str): - return s[0].upper() + (s[1:] if len(s) > 1 else '') + return s[0].upper() + (s[1:] if len(s) > 1 else "") - return ''.join([_up(word) for word in us_pattern.sub(' ', txt.strip().replace(',', '')).split()]) + return "".join([_up(word) for word in us_pattern.sub(" ", txt.strip().replace(",", "")).split()]) def underscore(txt: str) -> str: - return ws_pattern.sub('_', txt.strip()).replace(',', '').replace('-', '_') + return ws_pattern.sub("_", txt.strip()).replace(",", "").replace("-", "_") def lcamelcase(txt: str) -> str: @@ -36,13 +36,13 @@ def lcamelcase(txt: str) -> str: def be(entry: object) -> str: - """ Return a stringified version of object replacing Nones with empty strings """ - return str(entry).strip() if entry else '' + """Return a stringified version of object replacing Nones with empty strings""" + return str(entry).strip() if entry else "" def mangled_attribute_name(clsname: str, attributename: str) -> str: - """ Return the mangling we use for attributes definitions """ - return lcamelcase(clsname) + '__' + underscore(attributename) + """Return the mangling we use for attributes definitions""" + return lcamelcase(clsname) + "__" + underscore(attributename) split_col = 115 @@ -57,15 +57,15 @@ def sfx(uri: str) -> str: :param uri: uri to be suffixed :return: URI with suffix """ - return str(uri) + ('' if uri.endswith(('/', '#', '_', ':')) else '/') + return str(uri) + ("" if uri.endswith(("/", "#", "_", ":")) else "/") def uri_for(prefix: str, suffix: str) -> str: - """ Generator for predicate and identifier URI's """ - if ':' in prefix: + """Generator for predicate and identifier URI's""" + if ":" in prefix: return sfx(prefix) + suffix else: - return prefix + ':' + suffix + return prefix + ":" + suffix def split_line(txt: str, split_len: int = split_col) -> list[str]: @@ -74,7 +74,7 @@ def split_line(txt: str, split_len: int = split_col) -> list[str]: words = txt.split() cur_line = "" for word in words: - word += ' ' + word += " " if len(cur_line) + len(word) > split_len: out_lines.append(cur_line if cur_line else word) if not cur_line: @@ -89,23 +89,24 @@ def split_line(txt: str, split_len: int = split_col) -> list[str]: def wrapped_annotation(txt: str) -> str: rval = [] - for line in [line.strip() for line in txt.split('\n')]: + for line in [line.strip() for line in txt.split("\n")]: if len(line) > split_col: rval += split_line(line) else: rval.append(line) - return '\n\t'.join(rval) + return "\n\t".join(rval) + def shex_results_as_string(rslts) -> str: - """ Pretty print ShEx Evaluation result """ + """Pretty print ShEx Evaluation result""" # TODO: Add this method to ShEx itself - rval = [f"Evalutating: {str(rslts.focus)} against {str(rslts.start)}"] + rval = [f"Evaluating: {str(rslts.focus)} against {str(rslts.start)}"] if rslts.result: rval.append("Result: CONFORMS") else: rval.append("Result: NonConforming") - rval += rslts.reason.split('\n') - return '\n'.join(rval) + rval += rslts.reason.split("\n") + return "\n".join(rval) def is_empty(v: Any) -> bool: @@ -141,9 +142,9 @@ def remove_empty_items(obj: Any, hide_protected_keys: bool = False, inside: bool Note that this will also convert Decimals to floats or ints; this is necessary as both json dumpers and yaml dumpers will encode Decimal types by default. See https://github.com/linkml/linkml/issues - + This is easier than fixing the individual serializers, described here: - + - JSON: https://bugs.python.org/issue16535, https://stackoverflow.com/questions/1960516/python-json-serialize-a-decimal-object - YAML: https://stackoverflow.com/questions/21695705/dump-an-python-object-as-yaml-file/51261042, https://github.com/yaml/pyyaml/pull/372 @@ -154,20 +155,31 @@ def remove_empty_items(obj: Any, hide_protected_keys: bool = False, inside: bool """ if is_list(obj): # for discussion of logic, see: https://github.com/linkml/linkml-runtime/issues/42 - obj_list = [e for e in [remove_empty_items(l, hide_protected_keys=hide_protected_keys, inside=True) - for l in obj if l != '_root'] if not is_empty(e)] + obj_list = [ + e + for e in [ + remove_empty_items(i, hide_protected_keys=hide_protected_keys, inside=True) for i in obj if i != "_root" + ] + if not is_empty(e) + ] return obj_list if not inside or not is_empty(obj_list) else None elif is_dict(obj): - obj_dict = {k: v for k, v in [(k2, remove_empty_items(v2, hide_protected_keys=hide_protected_keys, inside=True)) - for k2, v2 in items(obj)] if not is_empty(v)} + obj_dict = { + k: v + for k, v in [ + (k2, remove_empty_items(v2, hide_protected_keys=hide_protected_keys, inside=True)) + for k2, v2 in items(obj) + ] + if not is_empty(v) + } # https://github.com/linkml/linkml/issues/119 # Remove the additional level of nesting with enums - if len(obj_dict) == 1 and list(obj_dict.keys())[0] == '_code': - enum_text = list(obj_dict.values())[0].get('text', None) + if len(obj_dict) == 1 and list(obj_dict.keys())[0] == "_code": + enum_text = list(obj_dict.values())[0].get("text", None) if enum_text is not None: return enum_text - if hide_protected_keys and len(obj_dict) == 1 and str(list(obj_dict.keys())[0]).startswith('_'): + if hide_protected_keys and len(obj_dict) == 1 and str(list(obj_dict.keys())[0]).startswith("_"): inner_element = list(obj_dict.values())[0] if isinstance(inner_element, dict): obj_dict = inner_element @@ -178,7 +190,7 @@ def remove_empty_items(obj: Any, hide_protected_keys: bool = False, inside: bool # note that attempting to implement https://bugs.python.org/issue16535 # will not work for yaml serializations v = str(obj) - if '.' in v and not v.endswith('.0'): + if "." in v and not v.endswith(".0"): return float(obj) else: return int(obj) diff --git a/linkml_runtime/utils/inference_utils.py b/linkml_runtime/utils/inference_utils.py index c8545d78..c8243cee 100644 --- a/linkml_runtime/utils/inference_utils.py +++ b/linkml_runtime/utils/inference_utils.py @@ -1,11 +1,12 @@ import logging -from dataclasses import field, dataclass +from dataclasses import dataclass, field from enum import Enum -from typing import Union, Optional, Any, Callable +from typing import Any, Callable, Optional, Union + from jsonasobj2 import JsonObj, items from linkml_runtime import SchemaView -from linkml_runtime.linkml_model import SlotDefinitionName, PermissibleValue, ClassDefinitionName +from linkml_runtime.linkml_model import ClassDefinitionName, PermissibleValue, SlotDefinitionName from linkml_runtime.utils.enumerations import EnumDefinitionImpl from linkml_runtime.utils.eval_utils import eval_expr from linkml_runtime.utils.walker_utils import traverse_object_tree @@ -16,6 +17,7 @@ RESOLVE_FUNC = Callable[[str, Any], Any] + def obj_as_dict_nonrecursive(obj: YAMLRoot, resolve_function: RESOLVE_FUNC = None) -> dict[str, Any]: """ Translates an object into a dict, for the purposes of input into formatted strings @@ -29,6 +31,7 @@ def obj_as_dict_nonrecursive(obj: YAMLRoot, resolve_function: RESOLVE_FUNC = Non else: return {k: v for k, v in vars(obj).items()} + @dataclass class Config: """ @@ -37,6 +40,7 @@ class Config: - slot.string_serialization - slot.equals_expression """ + use_string_serialization: bool = field(default_factory=lambda: True) parse_string_serialization: bool = field(default_factory=lambda: False) use_rules: bool = field(default_factory=lambda: False) @@ -48,14 +52,19 @@ class Policy(Enum): """ Policy for when inferred values differ from already set values """ + STRICT = "strict" OVERRIDE = "override" KEEP = "keep" -def generate_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName], schemaview: SchemaView, - class_name: Union[str, ClassDefinitionName] = None, - config: Config = Config()) -> Optional[Any]: +def generate_slot_value( + obj: YAMLRoot, + slot_name: Union[str, SlotDefinitionName], + schemaview: SchemaView, + class_name: Union[str, ClassDefinitionName] = None, + config: Config = Config(), +) -> Optional[Any]: """ Infer the value of a slot for a given object @@ -76,7 +85,7 @@ def generate_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName] mapped_slot = schemaview.slot_name_mappings()[slot_name] slot_name = mapped_slot.name slot = schemaview.induced_slot(slot_name, class_name) - logger.debug(f' CONF={config}') + logger.debug(f" CONF={config}") if config.use_string_serialization: if slot.string_serialization: if isinstance(obj, JsonObj): @@ -88,13 +97,18 @@ def generate_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName] if isinstance(obj, JsonObj): return eval_expr(slot.equals_expression, **obj_as_dict_nonrecursive(obj, config.resolve_function)) if config.use_rules: - raise NotImplementedError(f'Rules not implemented for {config}') + raise NotImplementedError(f"Rules not implemented for {config}") return None -def infer_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName], schemaview: SchemaView, - class_name: Union[str, ClassDefinitionName] = None, - policy: Policy = Policy.STRICT, config: Config = Config()): +def infer_slot_value( + obj: YAMLRoot, + slot_name: Union[str, SlotDefinitionName], + schemaview: SchemaView, + class_name: Union[str, ClassDefinitionName] = None, + policy: Policy = Policy.STRICT, + config: Config = Config(), +): """ Infer the value of a slot for an object @@ -109,24 +123,28 @@ def infer_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName], s if v is not None and policy == Policy.KEEP: return v new_v = generate_slot_value(obj, slot_name, schemaview, class_name=class_name, config=config) - logger.debug(f'SETTING {slot_name} = {new_v} // current={v}, {policy}') + logger.debug(f"SETTING {slot_name} = {new_v} // current={v}, {policy}") if new_v: # check if new value is different; not str check is necessary as enums may not be converted if v is not None and new_v != v and str(new_v) != str(v): if policy == Policy.STRICT: - raise ValueError(f'Inconsistent value {v} != {new_v} for {slot_name} for {obj}') + raise ValueError(f"Inconsistent value {v} != {new_v} for {slot_name} for {obj}") elif policy == Policy.OVERRIDE: setattr(obj, slot_name, new_v) obj.__post_init__() else: setattr(obj, slot_name, new_v) - #print(f'CALLING POST INIT ON {obj} from {slot_name} = {new_v}') + # print(f'CALLING POST INIT ON {obj} from {slot_name} = {new_v}') obj.__post_init__() -def infer_all_slot_values(obj: YAMLRoot, schemaview: SchemaView, - class_name: Union[str, ClassDefinitionName] = None, - policy: Policy = Policy.STRICT, config: Config = Config()): +def infer_all_slot_values( + obj: YAMLRoot, + schemaview: SchemaView, + class_name: Union[str, ClassDefinitionName] = None, + policy: Policy = Policy.STRICT, + config: Config = Config(), +): """ Walks object tree inferring all slot values. @@ -140,13 +158,17 @@ def infer_all_slot_values(obj: YAMLRoot, schemaview: SchemaView, :param config: :return: """ + def infer(in_obj: YAMLRoot): - logger.debug(f'INFER={in_obj}') - if isinstance(in_obj, YAMLRoot) and not isinstance(in_obj, EnumDefinitionImpl) and not isinstance(in_obj, PermissibleValue): + logger.debug(f"INFER={in_obj}") + if ( + isinstance(in_obj, YAMLRoot) + and not isinstance(in_obj, EnumDefinitionImpl) + and not isinstance(in_obj, PermissibleValue) + ): for k, v in vars(in_obj).items(): - #print(f' ISV={k} curr={v} policy={policy} in_obj={type(in_obj)}') + # print(f' ISV={k} curr={v} policy={policy} in_obj={type(in_obj)}') infer_slot_value(in_obj, k, schemaview, class_name=class_name, policy=policy, config=config) return in_obj - traverse_object_tree(obj, infer) - + traverse_object_tree(obj, infer) diff --git a/linkml_runtime/utils/introspection.py b/linkml_runtime/utils/introspection.py index 0f50aa77..32b99e66 100644 --- a/linkml_runtime/utils/introspection.py +++ b/linkml_runtime/utils/introspection.py @@ -9,8 +9,8 @@ from linkml_runtime.utils.schemaview import SchemaView from linkml_runtime.utils.yamlutils import YAMLRoot +SCHEMA_PATH_VAR = "schema_path" -SCHEMA_PATH_VAR = 'schema_path' def package_schema_path(package: Union[str, ModuleType]) -> Path: if isinstance(package, str): @@ -36,6 +36,7 @@ def package_schemaview(package: str, **kwargs) -> SchemaView: """ return SchemaView(get_schema_string(package, **kwargs)) + def object_schemaview(obj: YAMLRoot) -> SchemaView: """ Given an object that instantiates a LinkML class, return the corresponding SchemaView @@ -46,6 +47,7 @@ def object_schemaview(obj: YAMLRoot) -> SchemaView: cls = type(obj) return package_schemaview(cls.__module__) + def object_class_definition(obj: YAMLRoot) -> ClassDefinition: """ Given an object that instantiates a LinkML class, return its ClassDefinition @@ -56,5 +58,3 @@ def object_class_definition(obj: YAMLRoot) -> ClassDefinition: sv = object_schemaview(obj) cls = type(obj) return sv.get_class(cls.class_name) - - diff --git a/linkml_runtime/utils/metamodelcore.py b/linkml_runtime/utils/metamodelcore.py index 46335b64..9287466b 100644 --- a/linkml_runtime/utils/metamodelcore.py +++ b/linkml_runtime/utils/metamodelcore.py @@ -1,22 +1,20 @@ import builtins import datetime import re +import sys from dataclasses import field from decimal import Decimal -import sys -from typing import Union, Optional +from typing import Optional, Union from urllib.parse import urlparse -from rdflib import Literal, BNode, URIRef +from rdflib import BNode, Literal, URIRef from rdflib.namespace import is_ncname from rdflib.term import Identifier as rdflib_Identifier from linkml_runtime.utils.namespaces import Namespaces from linkml_runtime.utils.strictness import is_strict - -from linkml_runtime.utils.uri_validator import validate_uri -from linkml_runtime.utils.uri_validator import validate_uri_reference -from linkml_runtime.utils.uri_validator import validate_curie +from linkml_runtime.utils.uri_validator import validate_curie, validate_uri, validate_uri_reference +from linkml_runtime.utils.yamlutils import TypedNode if sys.version_info < (3, 11): import isodate @@ -27,32 +25,31 @@ # =========================== # Fields for use in dataclass # =========================== -from linkml_runtime.utils.yamlutils import TypedNode def empty_list(): - """ Return a field with a list factory """ + """Return a field with a list factory""" return field(default_factory=list) def empty_dict(): - """ Return a field with a dictionary factory """ + """Return a field with a dictionary factory""" return field(default_factory=dict) def addl_args(): rval = field(default_factory=dict) - rval.name = '**args' + rval.name = "**args" return rval def empty_set(): - """" Return a field with a set factory """ + """ " Return a field with a set factory""" return field(default_factory=set) def bnode(): - """ Return a field with a BNode factory """ + """Return a field with a BNode factory""" return field(default_factory=lambda: BNode().n3()) @@ -61,7 +58,8 @@ def bnode(): class NCName(str): - """ Wrapper for NCName class """ + """Wrapper for NCName class""" + def __init__(self, v: str) -> None: if is_strict() and not self.is_valid(v): raise ValueError(f"{TypedNode.yaml_loc(v)}{v}: Not a valid NCName") @@ -70,11 +68,12 @@ def __init__(self, v: str) -> None: @classmethod def is_valid(cls, v: str) -> bool: - return is_ncname(v) if v else True # Empty is default name + return is_ncname(v) if v else True # Empty is default name class Identifier(str, TypedNode): - """ A datatype that can be a URI, CURIE or a BNode """ + """A datatype that can be a URI, CURIE or a BNode""" + def __init__(self, v: Union[str, URIRef, BNode, "URIorCURIE", "Identifier"]) -> None: v = str(v) if not isinstance(v, str) else v if is_strict() and not self.is_valid(v): @@ -85,14 +84,14 @@ def __init__(self, v: Union[str, URIRef, BNode, "URIorCURIE", "Identifier"]) -> def is_valid(cls, v: Union[str, URIRef, BNode, "URIorCURIE", "Identifier"]) -> bool: if v is None: return False - if v.startswith('_:'): - pfx, ln = v.split(':') + if v.startswith("_:"): + pfx, ln = v.split(":") return len(ln) == 1 and bool(Curie.term_name.match(ln)) else: return URIorCURIE.is_valid(v) def as_identifier(self, nsm: Optional[Namespaces]) -> Optional[rdflib_Identifier]: - if self.startswith('_:'): + if self.startswith("_:"): return BNode(self) elif URIorCURIE.is_absolute(self): return URIRef(self) @@ -102,7 +101,8 @@ def as_identifier(self, nsm: Optional[Namespaces]) -> Optional[rdflib_Identifier class URIorCURIE(Identifier): - """ A datatype that can either be a URI or a CURIE """ + """A datatype that can either be a URI or a CURIE""" + def __init__(self, v: Union[str, URIRef, "Curie", "URIorCURIE"]) -> None: if is_strict() and not URIorCURIE.is_valid(v): raise ValueError(f"{v} is not a valid URI or CURIE") @@ -128,10 +128,11 @@ def is_absolute(v: str) -> bool: def is_curie(v: str, nsm: Optional[Namespaces] = None) -> bool: if not validate_curie(v): return False - if ':' in v and '://' not in v: - ns, ln = v.split(':', 1) - return len(ns) == 0 or (NCName.is_valid(ns) and - (nsm is None or any(ns == nsns for nsns, _ in nsm.namespaces()))) + if ":" in v and "://" not in v: + ns, ln = v.split(":", 1) + return len(ns) == 0 or ( + NCName.is_valid(ns) and (nsm is None or any(ns == nsns for nsns, _ in nsm.namespaces())) + ) return False def as_uri(self, nsm: Namespaces) -> Optional[URIRef]: @@ -141,8 +142,8 @@ def as_uri(self, nsm: Namespaces) -> Optional[URIRef]: class URI(URIorCURIE): - """ A relative absolute URI - """ + """A relative absolute URI""" + def __init__(self, v: str) -> None: if is_strict() and not URI.is_valid(v): raise ValueError(f"'{v}': is not a valid URI") @@ -159,8 +160,8 @@ def is_valid(cls, v: str) -> bool: class Curie(URIorCURIE): + """Wrapper for an element that MUST be represented as a CURIE""" - """ Wrapper for an element that MUST be represented as a CURIE """ def __init__(self, v: str) -> None: if is_strict() and not self.is_valid(v): raise ValueError(f"{v} is not a valid CURIE") @@ -172,7 +173,7 @@ def __init__(self, v: str) -> None: @classmethod def ns_ln(cls, v: str) -> Optional[tuple[str, str]]: # See if this is indeed a valid CURIE, ie, it can be split by a colon - curie_split = v.split(':', 1) + curie_split = v.split(":", 1) if len(curie_split) == 1: # there is no ':' character in the string, ie, it is not a valid CURIE return None @@ -188,12 +189,12 @@ def is_valid(cls, v: str) -> bool: if not validate_curie(v): return False pnln = cls.ns_ln(v) - #return pnln is not None and (not pnln[0] or isinstance(pnln[0], PN_PREFIX)) + # return pnln is not None and (not pnln[0] or isinstance(pnln[0], PN_PREFIX)) return pnln is not None # This code was extracted from the termorcurie package of the rdfa def as_uri(self, nsm: Namespaces) -> Optional[URIRef]: - """ Return the URI for the CURIE if a mapping is available, otherwise return None """ + """Return the URI for the CURIE if a mapping is available, otherwise return None""" try: return nsm.uri_for(self) except ValueError: @@ -202,9 +203,10 @@ def as_uri(self, nsm: Namespaces) -> Optional[URIRef]: class Bool: - """ Wrapper for boolean datatype """ - bool_true = re.compile(r'([Tt]rue)|(1)$') - bool_false = re.compile(r'([Ff]alse)|(0)$') + """Wrapper for boolean datatype""" + + bool_true = re.compile(r"([Tt]rue)|(1)$") + bool_false = re.compile(r"([Ff]alse)|(0)$") def __new__(cls, v: Union[str, bool, "Bool"]) -> bool: if isinstance(v, bool): @@ -219,12 +221,13 @@ def __new__(cls, v: Union[str, bool, "Bool"]) -> bool: @classmethod def is_valid(cls, v: str) -> bool: - """ Determine whether the string v is a valid instance of bool """ + """Determine whether the string v is a valid instance of bool""" return isinstance(v, bool) or cls.bool_true.match(str(v)) or cls.bool_false.match(str(v)) class XSDTime(str, TypedNode): - """ Wrapper for time datatype """ + """Wrapper for time datatype""" + def __new__(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) -> str: if is_strict() and not cls.is_valid(value): raise ValueError(f"{value} is not a valid time") @@ -253,7 +256,8 @@ def is_valid(cls, value: Union[str, datetime.time, datetime.datetime, Literal]) class XSDDate(str, TypedNode): - """ Wrapper for date datatype """ + """Wrapper for date datatype""" + def __new__(cls, value: Union[str, datetime.date, Literal]) -> str: if is_strict() and not cls.is_valid(value): raise ValueError(f"{value} is not a valid date") @@ -277,7 +281,7 @@ def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool: value = value.value if isinstance(value, datetime.date): value = value.isoformat() - if not re.match(r'^\d{4}-\d{2}-\d{2}$', value): + if not re.match(r"^\d{4}-\d{2}-\d{2}$", value): return False try: if sys.version_info >= (3, 11): @@ -290,7 +294,8 @@ def is_valid(cls, value: Union[str, datetime.date, Literal]) -> bool: class XSDDateTime(str, TypedNode): - """ Wrapper for date time dataclass """ + """Wrapper for date time dataclass""" + def __new__(cls, value: Union[str, datetime.datetime, Literal]) -> str: if is_strict() and not cls.is_valid(value): raise ValueError(f"{value} is not a valid datetime") @@ -299,13 +304,13 @@ def __new__(cls, value: Union[str, datetime.datetime, Literal]) -> str: try: if not isinstance(value, datetime.datetime): if sys.version_info >= (3, 11): - value = datetime.datetime.fromisoformat(value) # Note that this handles non 'T' format as well + value = datetime.datetime.fromisoformat(value) # Note that this handles non 'T' format as well else: if "T" in str(value): value = isodate.parse_datetime(value) elif " " in value.strip(): - value = isodate.parse_datetime("T".join(value.strip().split(' ', 1))) - else: + value = isodate.parse_datetime("T".join(value.strip().split(" ", 1))) + else: # As datetime.fromisoformat allows dates to be parsed as datetime we do the same. value = isodate.parse_datetime(f"{value.strip()}T00:00:00") return value.isoformat() @@ -327,7 +332,7 @@ def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool: if "T" in str(value): isodate.parse_datetime(value) elif " " in value.strip(): - isodate.parse_datetime("T".join(value.strip().split(' ', 1))) + isodate.parse_datetime("T".join(value.strip().split(" ", 1))) else: datetime.datetime.fromisoformat(value) except (ValueError, TypeError): @@ -336,10 +341,10 @@ def is_valid(cls, value: Union[str, datetime.datetime, Literal]) -> bool: class NodeIdentifier(Identifier): - """ A RDFLib Identifier that represents a URI, CURIE or BNode in a model """ + """A RDFLib Identifier that represents a URI, CURIE or BNode in a model""" def __new__(cls, v: Union[str, URIRef, URIorCURIE, "NodeIdentifier", BNode]) -> "NodeIdentifier": - if hasattr(v, 'id'): # Allows passing instances of identified objects + if hasattr(v, "id"): # Allows passing instances of identified objects v = v.id if isinstance(v, NodeIdentifier): if is_strict() and not issubclass(type(v), cls): @@ -356,12 +361,12 @@ def __post_init__(self): class ElementIdentifier(NodeIdentifier): - """ A URIorCURIE that represents an element in a model """ + """A URIorCURIE that represents an element in a model""" def __new__(cls, v: Union[str, URIRef, URIorCURIE, NodeIdentifier, "ElementIdentifier"]) -> "ElementIdentifier": - if hasattr(v, 'id'): # Allows passing instances of identified objects + if hasattr(v, "id"): # Allows passing instances of identified objects v = v.id - if is_strict() and (type(v) is BNode or str(v).startswith('_:')): + if is_strict() and (type(v) is BNode or str(v).startswith("_:")): raise ValueError(f"Invalid identifier type for {cls.__name__}: {v} ({type(v).__name__})") return super().__new__(cls, v) diff --git a/linkml_runtime/utils/namespaces.py b/linkml_runtime/utils/namespaces.py index 13a3dc06..1de25c37 100644 --- a/linkml_runtime/utils/namespaces.py +++ b/linkml_runtime/utils/namespaces.py @@ -2,13 +2,13 @@ from typing import Any, Optional, Union from prefixcommons import curie_util -from rdflib import Namespace, URIRef, Graph, BNode +from prefixmaps.io.parser import load_context +from rdflib import BNode, Graph, Namespace, URIRef from rdflib.namespace import is_ncname from requests.structures import CaseInsensitiveDict -from prefixmaps.io.parser import load_context -from linkml_runtime.utils.yamlutils import TypedNode from linkml_runtime.utils.uri_validator import validate_uri +from linkml_runtime.utils.yamlutils import TypedNode META_NS = "meta" META_URI = "https://w3id.org/linkml/meta" @@ -25,7 +25,7 @@ "obo_context", "ro_vocab_context", "semweb_context", - "semweb_vocab_context" + "semweb_vocab_context", ] PREFIXMAPS_CONTEXTS = [ "bioportal", @@ -36,29 +36,30 @@ "merged", "merged.oak", "obo", - "prefixcc" + "prefixcc", ] class Namespaces(CaseInsensitiveDict): - """ Namespace manager. Functions as both a dictionary and a python - namespace. + """Namespace manager. Functions as both a dictionary and a python + namespace. + + Supports: namespaces.NS [= uri] + namespaces[NS] [= uri] + namespaces._default [= uri] # namespace for ':' + namespaces._base [= uri] # namespace for @base - Supports: namespaces.NS [= uri] - namespaces[NS] [= uri] - namespaces._default [= uri] # namespace for ':' - namespaces._base [= uri] # namespace for @base + Functions: namespaces.curie_for(uri) --> curie + namespaces.prefix_for(uri_or_curie) --> NCName + namespaces.add_prefixmap(map name) + """ - Functions: namespaces.curie_for(uri) --> curie - namespaces.prefix_for(uri_or_curie) --> NCName - namespaces.add_prefixmap(map name) - """ - _default_key = '@default' - _base_key = '@base' + _default_key = "@default" + _base_key = "@base" # BNODE management -- when the namespace is '_', we map the ln via _bnodes to a new bnode - _bnodes = {} # BNode to BNode map - _empty_bnode = BNode() # Node for '_:' + _bnodes = {} # BNode to BNode map + _empty_bnode = BNode() # Node for '_:' def __init__(self, g: Optional[Graph] = None, *args, **kwargs): super().__init__(*args, **kwargs) @@ -66,7 +67,7 @@ def __init__(self, g: Optional[Graph] = None, *args, **kwargs): self.from_graph(g) def __setitem__(self, key, value): - if key == '_': + if key == "_": if not value: if self._empty_bnode not in self._bnodes: self._bnodes[self._empty_bnode] = BNode() @@ -79,7 +80,7 @@ def __setitem__(self, key, value): elif is_ncname(key): v = Namespace(str(value)) if key in self and self[key] != v: - logger = logging.getLogger('linkml_runtime.Namespaces') + logger = logging.getLogger("linkml_runtime.Namespaces") logger.warning(f"{key} namespace is already mapped to {self[key]} - Overriding with mapping to {v}") super().__setitem__(key, v) @@ -90,7 +91,7 @@ def __getattr__(self, item): return self[item] def __setattr__(self, key: str, value): - if key.startswith('_') and len(key) > 1: + if key.startswith("_") and len(key) > 1: super().__setattr__(key, value) else: self[key] = value @@ -149,7 +150,7 @@ def curie_for(self, uri: Any, default_ok: bool = True, pythonform: bool = False) if pythonform: default_ok = False - match: tuple[str, Optional[Namespace]] = ('', None) # match string / prefix + match: tuple[str, Optional[Namespace]] = ("", None) # match string / prefix uri_string = str(uri) # Find the longest match for the URI, self.items() is a list of (prefix/namespace, uri base prefix) tuples @@ -159,8 +160,9 @@ def curie_for(self, uri: Any, default_ok: bool = True, pythonform: bool = False) if uri_string.startswith(uri_base_string): # default key and base key are `@default` `@base` respectively # at this point match[0] is '', match[1] is None - if len(uri_base_string) > len(match[0]) and \ - (default_ok or namespace not in (Namespaces._default_key, Namespaces._base_key)): + if len(uri_base_string) > len(match[0]) and ( + default_ok or namespace not in (Namespaces._default_key, Namespaces._base_key) + ): match = (uri_base_string, namespace) # check if length of uri_base_string is > 0, now after basically assigning it to be the URI base string @@ -170,7 +172,7 @@ def curie_for(self, uri: Any, default_ok: bool = True, pythonform: bool = False) # uppercase the namespace namespace = match[1].upper() # match[0] is the URI base string, so we remove that from the incoming URI - leftover_uri = uri_string.replace((match[0]), '') + leftover_uri = uri_string.replace((match[0]), "") if not leftover_uri: return f"URIRef(str({namespace}))" # why? @@ -180,11 +182,11 @@ def curie_for(self, uri: Any, default_ok: bool = True, pythonform: bool = False) return f'{namespace}["{leftover_uri}"]' else: if match[1] == Namespaces._default_key: - return uri_string.replace(match[0], ':') + return uri_string.replace(match[0], ":") elif match[1] == Namespaces._base_key: - return uri_string.replace(match[0], '') + return uri_string.replace(match[0], "") else: - return uri_string.replace(match[0], match[1] + ':') + return uri_string.replace(match[0], match[1] + ":") return None def prefix_for(self, uri_or_curie: Any, case_shift: bool = True) -> Optional[str]: @@ -192,14 +194,14 @@ def prefix_for(self, uri_or_curie: Any, case_shift: bool = True) -> Optional[str def prefix_suffix(self, uri_or_curie: Any, case_shift: bool = True) -> tuple[Optional[str], Optional[str]]: uri_or_curie = str(uri_or_curie) - if '://' in uri_or_curie: + if "://" in uri_or_curie: uri_or_curie = self.curie_for(uri_or_curie) if not uri_or_curie: return None, None - if ':' in uri_or_curie: - pfx, sfx = uri_or_curie.split(':') + if ":" in uri_or_curie: + pfx, sfx = uri_or_curie.split(":") else: - pfx, sfx = uri_or_curie, '' + pfx, sfx = uri_or_curie, "" return self._cased_key(pfx) if case_shift else pfx, sfx def uri_for(self, uri_or_curie: Any) -> URIRef: @@ -210,12 +212,12 @@ def uri_for(self, uri_or_curie: Any) -> URIRef: :return: Corresponding URI """ uri_or_curie_str = str(uri_or_curie) - if '://' in uri_or_curie_str: + if "://" in uri_or_curie_str: return URIRef(uri_or_curie_str) - if ':\\' in uri_or_curie_str: # Windows drive letters + if ":\\" in uri_or_curie_str: # Windows drive letters return URIRef(uri_or_curie_str) - if ':' in uri_or_curie_str: - prefix, local = str(uri_or_curie_str).split(':', 1) + if ":" in uri_or_curie_str: + prefix, local = str(uri_or_curie_str).split(":", 1) if not prefix: prefix = self._default_key elif not is_ncname(prefix): @@ -228,27 +230,27 @@ def uri_for(self, uri_or_curie: Any) -> URIRef: return URIRef(self.join(self[prefix], local)) def uri_or_curie_for(self, prefix: Union[str, URIRef], suffix: str) -> str: - """ Return a CURIE for prefix/suffix if possible, else a URI """ - if isinstance(prefix, URIRef) or ':/' in str(prefix): + """Return a CURIE for prefix/suffix if possible, else a URI""" + if isinstance(prefix, URIRef) or ":/" in str(prefix): prefix_as_uri = str(prefix) for k, v in self.items(): - if not k.startswith('@') and prefix_as_uri == str(v): - return k + ':' + suffix + if not k.startswith("@") and prefix_as_uri == str(v): + return k + ":" + suffix return self.join(str(prefix), suffix) elif prefix not in self: raise ValueError(f"Unrecognized prefix: {prefix}") else: - return prefix + ':' + suffix + return prefix + ":" + suffix def load_graph(self, g: Graph) -> Graph: - """ Transfer all of the known namespaces into G """ + """Transfer all of the known namespaces into G""" for k, v in self.items(): - if not k.startswith('_') and not k.startswith('@'): + if not k.startswith("_") and not k.startswith("@"): g.bind(k, URIRef(v)) return g def from_graph(self, g: Graph) -> "Namespaces": - """ Transfer al bindings from G """ + """Transfer al bindings from G""" for ns, name in g.namespaces(): if ns: self[ns] = name @@ -270,7 +272,7 @@ def sfx(uri: str) -> str: :param uri: uri to be suffixed :return: URI with suffix """ - return str(uri) + ('' if uri.endswith(('/', '#')) else '/') + return str(uri) + ("" if uri.endswith(("/", "#")) else "/") def add_prefixmap(self, map_name: str, include_defaults: bool = True) -> None: """ diff --git a/linkml_runtime/utils/pattern.py b/linkml_runtime/utils/pattern.py index 941bd54e..f221b7ce 100644 --- a/linkml_runtime/utils/pattern.py +++ b/linkml_runtime/utils/pattern.py @@ -1,5 +1,6 @@ -from functools import lru_cache import re +from functools import lru_cache + # We might want to deprecate this method in favor of PatternResolver in the future def generate_patterns(schema_view) -> dict[str, str]: @@ -7,8 +8,8 @@ def generate_patterns(schema_view) -> dict[str, str]: the structured patterns in the settings. :param schema_view: SchemaView object with LinkML YAML already loaded - :return generated_patterns: dictionary with the - expanded structured patterns + :return generated_patterns: dictionary with the + expanded structured patterns """ resolver = PatternResolver(schema_view) @@ -77,11 +78,6 @@ def resolve(self, pattern: str) -> str: converted = pattern for item in reversed: - converted = ( - converted[: item["start"]] - + item["string"] - + converted[item["end"] :] - ) + converted = converted[: item["start"]] + item["string"] + converted[item["end"] :] return converted - diff --git a/linkml_runtime/utils/permissiblevalueimpl.py b/linkml_runtime/utils/permissiblevalueimpl.py index c7cd3043..57307aee 100644 --- a/linkml_runtime/utils/permissiblevalueimpl.py +++ b/linkml_runtime/utils/permissiblevalueimpl.py @@ -1,25 +1,28 @@ from dataclasses import dataclass -from typing import Any, Optional, ClassVar, Union +from typing import Any, ClassVar, Optional, Union from rdflib import URIRef from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import URIorCURIE, empty_list, URI +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import URI, URIorCURIE, empty_list from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str -from utils.enumerations import EnumDefinitionImpl -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") RenderingURI = URI + class PermissibleValueText(extended_str): pass + @dataclass class PermissibleValue(YAMLRoot): """ a permissible value, accompanied by intended text and an optional mapping to a concept URI """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = LINKML.PermissibleValue @@ -87,11 +90,17 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.see_also = [self.see_also] self.see_also = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.see_also] - if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE): + if self.deprecated_element_has_exact_replacement is not None and not isinstance( + self.deprecated_element_has_exact_replacement, URIorCURIE + ): self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement) - if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE): - self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement) + if self.deprecated_element_has_possible_replacement is not None and not isinstance( + self.deprecated_element_has_possible_replacement, URIorCURIE + ): + self.deprecated_element_has_possible_replacement = URIorCURIE( + self.deprecated_element_has_possible_replacement + ) if self.is_a is not None and not isinstance(self.is_a, PermissibleValueText): self.is_a = PermissibleValueText(self.is_a) @@ -110,31 +119,35 @@ class PvFormulaOptions(EnumDefinitionImpl): """ The formula used to generate the set of permissible values from the code_set values """ - CODE = PermissibleValue(text="CODE", - description="The permissible values are the set of possible codes in the code set") - CURIE = PermissibleValue(text="CURIE", - description="The permissible values are the set of CURIES in the code set") - URI = PermissibleValue(text="URI", - description="The permissible values are the set of code URIs in the code set") - FHIR_CODING = PermissibleValue(text="FHIR_CODING", - description="The permissible values are the set of FHIR coding elements derived from the code set") - - _defn = EnumDefinition( - name="PvFormulaOptions", - description="The formula used to generate the set of permissible values from the code_set values", + + CODE = PermissibleValue( + text="CODE", description="The permissible values are the set of possible codes in the code set" ) + CURIE = PermissibleValue(text="CURIE", description="The permissible values are the set of CURIES in the code set") + URI = PermissibleValue(text="URI", description="The permissible values are the set of code URIs in the code set") + FHIR_CODING = PermissibleValue( + text="FHIR_CODING", + description="The permissible values are the set of FHIR coding elements derived from the code set", + ) + + # _defn = EnumDefinition( + # name="PvFormulaOptions", + # description="The formula used to generate the set of permissible values from the code_set values", + # ) + class PermissibleValueImpl(PermissibleValue): """ Permissible Value implementation """ + def __init__(self, *args, defn: EnumDefinitionImpl, **kwargs) -> None: - """ Record the referencing definition to allow the entry to be fleshed out from a terminology service """ + """Record the referencing definition to allow the entry to be fleshed out from a terminology service""" super().__init__(*args, **kwargs) self._defn = defn def __post_init__(self, **kwargs: dict[str, Any]) -> None: - """ Make sure that we are correctly situated in the containing definition """ + """Make sure that we are correctly situated in the containing definition""" if self.text in self._defn: if self._defn.permissible_values[self.text] != self: raise TypeError(f"Permissible value for code: {self.text} is already assigned") diff --git a/linkml_runtime/utils/ruleutils.py b/linkml_runtime/utils/ruleutils.py index a9821e70..b84424ef 100644 --- a/linkml_runtime/utils/ruleutils.py +++ b/linkml_runtime/utils/ruleutils.py @@ -1,8 +1,17 @@ import logging from dataclasses import dataclass +from linkml_runtime.linkml_model.meta import ( + AnonymousClassExpression, + ClassDefinition, + ClassDefinitionName, + ClassExpression, + ClassRule, + SlotDefinition, + SlotDefinitionName, + SlotExpression, +) from linkml_runtime.utils.schemaview import SchemaView -from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition, ClassExpression, ClassDefinitionName, ClassRule, AnonymousClassExpression, SlotExpression, SlotDefinitionName logger = logging.getLogger(__name__) @@ -11,36 +20,41 @@ class AtomicClassExpression: """ aka literal (https://en.wikipedia.org/wiki/Literal_(mathematical_logic)) """ + expression: ClassExpression negated: bool def __str__(self): if self.negated: - return f'NOT {self.expression}' + return f"NOT {self.expression}" else: return str(self.expression) + class ClassExpressionConjunction: """ conjunction of class literals """ + operands: AtomicClassExpression def __str__(self): - return ' AND '.join([str(op) for op in self.operands]) + return " AND ".join([str(op) for op in self.operands]) + @dataclass class DisjunctiveNormalFormClassExpression: """ A boolean combination of class expressions in Disjunctive Normal Form """ + operands: list[ClassExpressionConjunction] def __str__(self): - return ' OR '.join([str(op) for op in self.operands]) + return " OR ".join([str(op) for op in self.operands]) -def get_range_as_disjunction(slot: SlotExpression) -> set[ClassDefinitionName]: +def get_range_as_disjunction(slot: SlotExpression) -> set[ClassDefinitionName]: """ translate the range of a slot as defined by both range expressions and direct named class ranges to a disjunctive expression @@ -58,14 +72,16 @@ def get_range_as_disjunction(slot: SlotExpression) -> set[ClassDefinitionName]: if isinstance(slot.range_expression, ClassExpression): conjs.append(get_disjunction(slot.range_expression)) else: - logger.warning(f'Expected range_expression for {slot.name} to be a class expression, not {type(slot.range_expression)}') + logger.warning( + f"Expected range_expression for {slot.name} to be a class expression, not {type(slot.range_expression)}" + ) if len(conjs) == 0: if slot.range: conjs.append({slot.range}) else: - logger.warning(f'No range for {slot.name}') + logger.warning(f"No range for {slot.name}") if len(conjs) > 1: - raise Exception(f'Cannot determine range disjunction for {slot}, got conjunctions: {conjs}') + raise Exception(f"Cannot determine range disjunction for {slot}, got conjunctions: {conjs}") if len(conjs) == 0: return None else: @@ -82,8 +98,12 @@ def get_disjunction(cx: ClassExpression) -> set[ClassDefinitionName]: return disj -def subclass_to_rules(view: SchemaView, child: ClassDefinitionName, parent: ClassDefinitionName, - type_designator_slot: SlotDefinitionName = None) -> list[ClassRule]: +def subclass_to_rules( + view: SchemaView, + child: ClassDefinitionName, + parent: ClassDefinitionName, + type_designator_slot: SlotDefinitionName = None, +) -> list[ClassRule]: """ rolls up child class to parent class, turning class-specific slot_usages into rules :param view: @@ -98,10 +118,10 @@ def subclass_to_rules(view: SchemaView, child: ClassDefinitionName, parent: Clas if len(type_designators) == 1: type_designator_slot = type_designators[0] elif len(type_designators) > 1: - raise Exception(f'Multiple type designatirs: {type_designators}') + raise Exception(f"Multiple type designatirs: {type_designators}") else: - type_designator_slot = SlotDefinitionName('type') - rule.preconditions = AnonymousClassExpression(slot_conditions=[SlotDefinition('type', equals_string=child)]) + type_designator_slot = SlotDefinitionName("type") + rule.preconditions = AnonymousClassExpression(slot_conditions=[SlotDefinition("type", equals_string=child)]) rule.postconditions = AnonymousClassExpression(slot_conditions=child_slots) # ensure slots are declared for parent parent_slots = view.class_induced_slots(parent) @@ -116,12 +136,12 @@ def subclass_to_rules(view: SchemaView, child: ClassDefinitionName, parent: Clas def rule_subsumed_by_class(view: SchemaView, rule, cls: ClassDefinition): - induced_slots = view.class_induced_slots(cls.name) + # induced_slots = view.class_induced_slots(cls.name) return False def remove_redundant_rules(view: SchemaView, class_name: ClassDefinitionName): - induced_slots = view.class_induced_slots(class_name) + # induced_slots = view.class_induced_slots(class_name) cls = view.get_class(class_name) redundant_rules = [] for rule in cls.rules: @@ -130,8 +150,3 @@ def remove_redundant_rules(view: SchemaView, class_name: ClassDefinitionName): for rule in redundant_rules: cls.rules.remove(rule) return redundant_rules - - - - - diff --git a/linkml_runtime/utils/schema_as_dict.py b/linkml_runtime/utils/schema_as_dict.py index 6432479b..7268dda5 100644 --- a/linkml_runtime/utils/schema_as_dict.py +++ b/linkml_runtime/utils/schema_as_dict.py @@ -2,8 +2,8 @@ import yaml -from linkml_runtime.linkml_model.meta import SchemaDefinition from linkml_runtime.dumpers import json_dumper +from linkml_runtime.linkml_model.meta import SchemaDefinition def _remove_names(obj: Any, parent: Optional[str]) -> Any: @@ -42,7 +42,11 @@ def _remove_names(obj: Any, parent: Optional[str]) -> Any: :return: """ if isinstance(obj, dict): - return {k: _remove_names(v, k) for k, v in obj.items() if k != 'name' or parent is None or parent in ['slots', 'slot_usage', 'attributes']} + return { + k: _remove_names(v, k) + for k, v in obj.items() + if k != "name" or parent is None or parent in ["slots", "slot_usage", "attributes"] + } elif isinstance(obj, list): return [_remove_names(x, parent) for x in obj] else: @@ -61,15 +65,16 @@ def schema_as_dict(schema: SchemaDefinition) -> dict: :return: minimal canonical dictionary object """ obj = json_dumper.to_dict(schema) - if '@type' in obj: - del obj['@type'] - obj['prefixes'] = {k: v['prefix_reference'] for k, v in obj.get('prefixes', {}).items()} - for k, v in obj.get('enums', {}).items(): - for pv in v.get('permissible_values', {}).values(): - del pv['text'] + if "@type" in obj: + del obj["@type"] + obj["prefixes"] = {k: v["prefix_reference"] for k, v in obj.get("prefixes", {}).items()} + for k, v in obj.get("enums", {}).items(): + for pv in v.get("permissible_values", {}).values(): + del pv["text"] obj = _remove_names(obj, None) return obj + def schema_as_yaml_dump(schema: SchemaDefinition) -> str: """ Uses :func:`schema_as_dict` to generate a minimal YAML dump of the schema diff --git a/linkml_runtime/utils/schema_builder.py b/linkml_runtime/utils/schema_builder.py index b7d6024b..034ec0b9 100644 --- a/linkml_runtime/utils/schema_builder.py +++ b/linkml_runtime/utils/schema_builder.py @@ -1,10 +1,15 @@ from dataclasses import dataclass, fields -from typing import Union, Optional - -from linkml_runtime.linkml_model import (ClassDefinition, EnumDefinition, - PermissibleValue, Prefix, - SchemaDefinition, SlotDefinition, - TypeDefinition) +from typing import Optional, Union + +from linkml_runtime.linkml_model import ( + ClassDefinition, + EnumDefinition, + PermissibleValue, + Prefix, + SchemaDefinition, + SlotDefinition, + TypeDefinition, +) from linkml_runtime.utils.formatutils import underscore from linkml_runtime.utils.schema_as_dict import schema_as_dict @@ -87,10 +92,7 @@ def add_class( else: # Ensure that `cls` is a `ClassDefinition` object if not isinstance(cls, ClassDefinition): - msg = ( - f"cls must be a string, dict, or ClassDefinition, " - f"not {type(cls)!r}" - ) + msg = f"cls must be a string, dict, or ClassDefinition, " f"not {type(cls)!r}" raise TypeError(msg) cls_as_dict = {f.name: getattr(cls, f.name) for f in fields(cls)} @@ -105,9 +107,7 @@ def add_class( if isinstance(s, SlotDefinition): cls.attributes[s.name] = s else: - raise ValueError( - f"If use_attributes=True then slots must be SlotDefinitions" - ) + raise ValueError("If use_attributes=True then slots must be SlotDefinitions") else: for s in slots: cls.slots.append(s.name if isinstance(s, SlotDefinition) else s) @@ -186,10 +186,7 @@ def add_enum( else: # Ensure that `enum_def` is a `EnumDefinition` object if not isinstance(enum_def, EnumDefinition): - msg = ( - f"enum_def must be a `str`, `dict`, or `EnumDefinition`, " - f"not {type(enum_def)!r}" - ) + msg = f"enum_def must be a `str`, `dict`, or `EnumDefinition`, " f"not {type(enum_def)!r}" raise TypeError(msg) if enum_def.name in self.schema.enums and not replace_if_present: @@ -202,17 +199,14 @@ def add_enum( if isinstance(pv, str): pv = PermissibleValue(text=pv) elif not isinstance(pv, PermissibleValue): - msg = ( - f"A permissible value must be a `str` or " - f"a `PermissibleValue` object, not {type(pv)}" - ) + msg = f"A permissible value must be a `str` or " f"a `PermissibleValue` object, not {type(pv)}" raise TypeError(msg) enum_def.permissible_values[pv.text] = pv return self - def add_prefix(self, prefix: str, url: str, replace_if_present = False) -> "SchemaBuilder": + def add_prefix(self, prefix: str, url: str, replace_if_present=False) -> "SchemaBuilder": """ Adds a prefix for use with CURIEs @@ -237,7 +231,6 @@ def add_imports(self, *imports) -> "SchemaBuilder": self.schema.imports.extend(imports) return self - def add_defaults(self) -> "SchemaBuilder": """ Sets defaults, including: @@ -258,12 +251,12 @@ def add_defaults(self) -> "SchemaBuilder": return self def add_type( - self, - type: Union[TypeDefinition, dict, str], - typeof: str = None, - uri: str = None, - replace_if_present=False, - **kwargs + self, + type: Union[TypeDefinition, dict, str], + typeof: str = None, + uri: str = None, + replace_if_present=False, + **kwargs, ) -> "SchemaBuilder": """ Adds the type to the schema diff --git a/linkml_runtime/utils/schemaops.py b/linkml_runtime/utils/schemaops.py index 361d83b1..c7a6e677 100644 --- a/linkml_runtime/utils/schemaops.py +++ b/linkml_runtime/utils/schemaops.py @@ -1,9 +1,10 @@ from typing import Union -from linkml_runtime.utils.schemaview import SchemaView, CLASS_NAME +from linkml_runtime.utils.schemaview import CLASS_NAME, SchemaView CLASS_NAME_OR_LIST = Union[CLASS_NAME, list[CLASS_NAME]] + def roll_up(sv: SchemaView, classes: CLASS_NAME_OR_LIST = None, mixins=True, is_a=True, delete=True) -> None: """ rolls slots up to a set of ancestor classes @@ -21,7 +22,6 @@ def roll_up(sv: SchemaView, classes: CLASS_NAME_OR_LIST = None, mixins=True, is_ dels = set() for cn in classes: c = sv.get_class(cn) - slots = [] for d in sv.class_descendants(cn, reflexive=False, mixins=mixins, is_a=is_a): for sn in sv.class_slots(d): s = sv.induced_slot(sn, class_name=d) @@ -37,6 +37,7 @@ def roll_up(sv: SchemaView, classes: CLASS_NAME_OR_LIST = None, mixins=True, is_ sv.delete_class(d) sv.set_modified() + def roll_down(sv: SchemaView, classes: list[CLASS_NAME] = None, mixins=True, is_a=True, delete=True) -> None: """ rolls down to a set of descendant classes @@ -52,7 +53,6 @@ def roll_down(sv: SchemaView, classes: list[CLASS_NAME] = None, mixins=True, is_ dels = set() for cn in classes: c = sv.get_class(cn) - slots = [] for d in sv.class_ancestors(cn, reflexive=False, mixins=mixins, is_a=is_a): for sn in sv.class_slots(d): s = sv.induced_slot(sn, class_name=d) @@ -72,9 +72,5 @@ def roll_down(sv: SchemaView, classes: list[CLASS_NAME] = None, mixins=True, is_ if is_a and c.is_a is not None: del c.is_a for d in dels: - d_cls = sv.get_class(d) sv.delete_class(d) sv.set_modified() - - - diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 1be70a30..a9fbd246 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -1,37 +1,58 @@ +import collections +import logging import os import sys import uuid -import logging -import collections -from functools import lru_cache -from copy import copy, deepcopy +import warnings from collections import defaultdict, deque -from pathlib import Path, PurePath -from typing import Optional, TypeVar from collections.abc import Mapping -import warnings -from urllib.parse import urlparse +from copy import copy, deepcopy +from dataclasses import dataclass +from enum import Enum +from functools import lru_cache +from pathlib import Path, PurePath +from typing import Any, Optional, TypeVar, Union -from linkml_runtime.utils.namespaces import Namespaces from deprecated.classic import deprecated -from linkml_runtime.utils.context_utils import parse_import_map, map_import + +from linkml_runtime.exceptions import OrderingError +from linkml_runtime.linkml_model import ( + AnonymousSlotExpression, + ClassDefinition, + ClassDefinitionName, + Definition, + DefinitionName, + Element, + ElementName, + EnumDefinition, + EnumDefinitionName, + PermissibleValueText, + SchemaDefinition, + SchemaDefinitionName, + SlotDefinition, + SlotDefinitionName, + SubsetDefinition, + SubsetDefinitionName, + TypeDefinition, + TypeDefinitionName, +) +from linkml_runtime.utils.context_utils import map_import, parse_import_map from linkml_runtime.utils.formatutils import camelcase, is_empty, sfx, underscore +from linkml_runtime.utils.metamodelcore import URIorCURIE +from linkml_runtime.utils.namespaces import Namespaces from linkml_runtime.utils.pattern import PatternResolver -from linkml_runtime.linkml_model.meta import * -from linkml_runtime.exceptions import OrderingError -from enum import Enum logger = logging.getLogger(__name__) MAPPING_TYPE = str ## e.g. broad, exact, related, ... CACHE_SIZE = 1024 -SLOTS = 'slots' -CLASSES = 'classes' -ENUMS = 'enums' -SUBSETS = 'subsets' -TYPES = 'types' -WINDOWS = sys.platform == 'win32' +SLOTS = "slots" +CLASSES = "classes" +ENUMS = "enums" +SUBSETS = "subsets" +TYPES = "types" +WINDOWS = sys.platform == "win32" CLASS_NAME = Union[ClassDefinitionName, str] SLOT_NAME = Union[SlotDefinitionName, str] @@ -83,6 +104,7 @@ def _closure(f, x, reflexive=True, depth_first=True, **kwargs): def load_schema_wrap(path: str, **kwargs): # import here to avoid circular imports from linkml_runtime.loaders.yaml_loader import YAMLLoader + yaml_loader = YAMLLoader() schema: SchemaDefinition schema = yaml_loader.load(path, target_class=SchemaDefinition, **kwargs) @@ -114,6 +136,7 @@ class SchemaUsage: """ A usage of an element of a schema """ + used_by: ElementName slot: SlotDefinitionName metaslot: SlotDefinitionName @@ -152,9 +175,13 @@ class SchemaView: # cached hash _hash: Optional[int] = None - - def __init__(self, schema: Union[str, Path, SchemaDefinition], - importmap: Optional[dict[str, str]] = None, merge_imports: bool = False, base_dir: str = None): + def __init__( + self, + schema: Union[str, Path, SchemaDefinition], + importmap: Optional[dict[str, str]] = None, + merge_imports: bool = False, + base_dir: str = None, + ): if isinstance(schema, Path): schema = str(schema) if isinstance(schema, str): @@ -218,22 +245,22 @@ def load_import(self, imp: str, from_schema: SchemaDefinition = None): if from_schema is None: from_schema = self.schema from linkml_runtime import SCHEMA_DIRECTORY - default_import_map = { - "linkml:": str(SCHEMA_DIRECTORY) - } + + default_import_map = {"linkml:": str(SCHEMA_DIRECTORY)} importmap = {**default_import_map, **self.importmap} sname = map_import(importmap, self.namespaces, imp) if from_schema.source_file and not is_absolute_path(sname): base_dir = os.path.dirname(from_schema.source_file) else: base_dir = None - logger.info(f'Importing {imp} as {sname} from source {from_schema.source_file}; base_dir={base_dir}') - schema = load_schema_wrap(sname + '.yaml', base_dir=base_dir) + logger.info(f"Importing {imp} as {sname} from source {from_schema.source_file}; base_dir={base_dir}") + schema = load_schema_wrap(sname + ".yaml", base_dir=base_dir) return schema @lru_cache(None) - def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None, inject_metadata=True) -> list[ - SchemaDefinitionName]: + def imports_closure( + self, imports: bool = True, traverse: Optional[bool] = None, inject_metadata=True + ) -> list[SchemaDefinitionName]: """ Return all imports @@ -271,8 +298,8 @@ def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None, if traverse is not None: warnings.warn( - 'traverse behaves identically to imports and will be removed in a future version. Use imports instead.', - DeprecationWarning + "traverse behaves identically to imports and will be removed in a future version. Use imports instead.", + DeprecationWarning, ) if not imports or (not traverse and traverse is not None): @@ -313,9 +340,7 @@ def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None, if "/" in sn and ":" not in i: if WINDOWS: # This cannot be simplified. os.path.normpath() must be called before .as_posix() - i = PurePath( - os.path.normpath(PurePath(sn).parent / i) - ).as_posix() + i = PurePath(os.path.normpath(PurePath(sn).parent / i)).as_posix() else: i = os.path.normpath(str(Path(sn).parent / i)) todo.append(i) @@ -463,8 +488,9 @@ def all_slot(self, **kwargs) -> dict[SlotDefinitionName, SlotDefinition]: return self.all_slots(**kwargs) @lru_cache(None) - def all_slots(self, ordered_by=OrderedBy.PRESERVE, imports=True, attributes=True) -> dict[ - SlotDefinitionName, SlotDefinition]: + def all_slots( + self, ordered_by=OrderedBy.PRESERVE, imports=True, attributes=True + ) -> dict[SlotDefinitionName, SlotDefinition]: """ :param ordered_by: an enumerated parameter that returns all the slots in the order specified. :param imports: include imports closure @@ -610,7 +636,7 @@ def in_schema(self, element_name: ElementName) -> SchemaDefinitionName: """ ix = self.element_by_schema_map() if element_name not in ix: - raise ValueError(f'Element {element_name} not in any schema') + raise ValueError(f"Element {element_name} not in any schema") return ix[element_name] @lru_cache(None) @@ -733,8 +759,9 @@ def enum_parents(self, enum_name: ENUM_NAME, imports=False, mixins=False, is_a=T return self._parents(e, imports, mixins, is_a=is_a) @lru_cache(None) - def permissible_value_parent(self, permissible_value: str, enum_name: ENUM_NAME) -> Union[ - str, PermissibleValueText, None, ValueError]: + def permissible_value_parent( + self, permissible_value: str, enum_name: ENUM_NAME + ) -> Union[str, PermissibleValueText, None, ValueError]: """ :param enum_name: child enum name :param permissible_value: permissible value @@ -750,8 +777,9 @@ def permissible_value_parent(self, permissible_value: str, enum_name: ENUM_NAME) return [] @lru_cache(None) - def permissible_value_children(self, permissible_value: str, enum_name: ENUM_NAME) -> Union[ - str, PermissibleValueText, None, ValueError]: + def permissible_value_children( + self, permissible_value: str, enum_name: ENUM_NAME + ) -> Union[str, PermissibleValueText, None, ValueError]: """ :param enum_name: parent enum name :param permissible_value: permissible value @@ -852,8 +880,9 @@ def slot_children(self, slot_name: SLOT_NAME, imports=True, mixins=True, is_a=Tr return [x.name for x in elts if (x.is_a == slot_name and is_a) or (mixins and slot_name in x.mixins)] @lru_cache(None) - def class_ancestors(self, class_name: CLASS_NAME, imports=True, mixins=True, reflexive=True, is_a=True, - depth_first=True) -> list[ClassDefinitionName]: + def class_ancestors( + self, class_name: CLASS_NAME, imports=True, mixins=True, reflexive=True, is_a=True, depth_first=True + ) -> list[ClassDefinitionName]: """ Closure of class_parents method @@ -865,43 +894,49 @@ def class_ancestors(self, class_name: CLASS_NAME, imports=True, mixins=True, ref :param depth_first: :return: ancestor class names """ - return _closure(lambda x: self.class_parents(x, imports=imports, mixins=mixins, is_a=is_a), - class_name, - reflexive=reflexive, depth_first=depth_first) + return _closure( + lambda x: self.class_parents(x, imports=imports, mixins=mixins, is_a=is_a), + class_name, + reflexive=reflexive, + depth_first=depth_first, + ) @lru_cache(None) - def permissible_value_ancestors(self, permissible_value_text: str, - enum_name: ENUM_NAME, - reflexive=True, - depth_first=True) -> list[str]: + def permissible_value_ancestors( + self, permissible_value_text: str, enum_name: ENUM_NAME, reflexive=True, depth_first=True + ) -> list[str]: """ Closure of permissible_value_parents method :enum """ - return _closure(lambda x: self.permissible_value_parent(x, enum_name), - permissible_value_text, - reflexive=reflexive, - depth_first=depth_first) + return _closure( + lambda x: self.permissible_value_parent(x, enum_name), + permissible_value_text, + reflexive=reflexive, + depth_first=depth_first, + ) @lru_cache(None) - def permissible_value_descendants(self, permissible_value_text: str, - enum_name: ENUM_NAME, - reflexive=True, - depth_first=True) -> list[str]: + def permissible_value_descendants( + self, permissible_value_text: str, enum_name: ENUM_NAME, reflexive=True, depth_first=True + ) -> list[str]: """ Closure of permissible_value_children method :enum """ - return _closure(lambda x: self.permissible_value_children(x, enum_name), - permissible_value_text, - reflexive=reflexive, - depth_first=depth_first) + return _closure( + lambda x: self.permissible_value_children(x, enum_name), + permissible_value_text, + reflexive=reflexive, + depth_first=depth_first, + ) @lru_cache(None) - def enum_ancestors(self, enum_name: ENUM_NAME, imports=True, mixins=True, reflexive=True, is_a=True, - depth_first=True) -> list[EnumDefinitionName]: + def enum_ancestors( + self, enum_name: ENUM_NAME, imports=True, mixins=True, reflexive=True, is_a=True, depth_first=True + ) -> list[EnumDefinitionName]: """ Closure of enum_parents method @@ -913,13 +948,17 @@ def enum_ancestors(self, enum_name: ENUM_NAME, imports=True, mixins=True, reflex :param depth_first: :return: ancestor enum names """ - return _closure(lambda x: self.enum_parents(x, imports=imports, mixins=mixins, is_a=is_a), - enum_name, - reflexive=reflexive, depth_first=depth_first) + return _closure( + lambda x: self.enum_parents(x, imports=imports, mixins=mixins, is_a=is_a), + enum_name, + reflexive=reflexive, + depth_first=depth_first, + ) @lru_cache(None) - def type_ancestors(self, type_name: TYPES, imports=True, reflexive=True, depth_first=True) -> list[ - TypeDefinitionName]: + def type_ancestors( + self, type_name: TYPES, imports=True, reflexive=True, depth_first=True + ) -> list[TypeDefinitionName]: """ All ancestors of a type via typeof @@ -929,13 +968,14 @@ def type_ancestors(self, type_name: TYPES, imports=True, reflexive=True, depth_f :param depth_first: :return: ancestor class names """ - return _closure(lambda x: self.type_parents(x, imports=imports), - type_name, - reflexive=reflexive, depth_first=depth_first) + return _closure( + lambda x: self.type_parents(x, imports=imports), type_name, reflexive=reflexive, depth_first=depth_first + ) @lru_cache(None) - def slot_ancestors(self, slot_name: SLOT_NAME, imports=True, mixins=True, reflexive=True, is_a=True) -> list[ - SlotDefinitionName]: + def slot_ancestors( + self, slot_name: SLOT_NAME, imports=True, mixins=True, reflexive=True, is_a=True + ) -> list[SlotDefinitionName]: """ Closure of slot_parents method @@ -946,13 +986,14 @@ def slot_ancestors(self, slot_name: SLOT_NAME, imports=True, mixins=True, reflex :param reflexive: include self in set of ancestors :return: ancestor slot names """ - return _closure(lambda x: self.slot_parents(x, imports=imports, mixins=mixins, is_a=is_a), - slot_name, - reflexive=reflexive) + return _closure( + lambda x: self.slot_parents(x, imports=imports, mixins=mixins, is_a=is_a), slot_name, reflexive=reflexive + ) @lru_cache(None) - def class_descendants(self, class_name: CLASS_NAME, imports=True, mixins=True, reflexive=True, is_a=True) -> list[ - ClassDefinitionName]: + def class_descendants( + self, class_name: CLASS_NAME, imports=True, mixins=True, reflexive=True, is_a=True + ) -> list[ClassDefinitionName]: """ Closure of class_children method @@ -963,12 +1004,14 @@ def class_descendants(self, class_name: CLASS_NAME, imports=True, mixins=True, r :param reflexive: include self in set of descendants :return: descendants class names """ - return _closure(lambda x: self.class_children(x, imports=imports, mixins=mixins, is_a=is_a), class_name, - reflexive=reflexive) + return _closure( + lambda x: self.class_children(x, imports=imports, mixins=mixins, is_a=is_a), class_name, reflexive=reflexive + ) @lru_cache(None) - def slot_descendants(self, slot_name: SLOT_NAME, imports=True, mixins=True, reflexive=True, is_a=True) -> list[ - SlotDefinitionName]: + def slot_descendants( + self, slot_name: SLOT_NAME, imports=True, mixins=True, reflexive=True, is_a=True + ) -> list[SlotDefinitionName]: """ Closure of slot_children method @@ -979,8 +1022,9 @@ def slot_descendants(self, slot_name: SLOT_NAME, imports=True, mixins=True, refl :param reflexive: include self in set of descendants :return: descendants slot names """ - return _closure(lambda x: self.slot_children(x, imports=imports, mixins=mixins, is_a=is_a), slot_name, - reflexive=reflexive) + return _closure( + lambda x: self.slot_children(x, imports=imports, mixins=mixins, is_a=is_a), slot_name, reflexive=reflexive + ) @lru_cache(None) def class_roots(self, imports=True, mixins=True, is_a=True) -> list[ClassDefinitionName]: @@ -991,9 +1035,11 @@ def class_roots(self, imports=True, mixins=True, is_a=True) -> list[ClassDefinit :param is_a: include is_a parents (default is True) :return: """ - return [c - for c in self.all_classes(imports=imports) - if self.class_parents(c, mixins=mixins, is_a=is_a, imports=imports) == []] + return [ + c + for c in self.all_classes(imports=imports) + if self.class_parents(c, mixins=mixins, is_a=is_a, imports=imports) == [] + ] @lru_cache(None) def class_leaves(self, imports=True, mixins=True, is_a=True) -> list[ClassDefinitionName]: @@ -1004,9 +1050,11 @@ def class_leaves(self, imports=True, mixins=True, is_a=True) -> list[ClassDefini :param is_a: include is_a parents (default is True) :return: """ - return [c - for c in self.all_classes(imports=imports) - if self.class_children(c, mixins=mixins, is_a=is_a, imports=imports) == []] + return [ + c + for c in self.all_classes(imports=imports) + if self.class_children(c, mixins=mixins, is_a=is_a, imports=imports) == [] + ] @lru_cache(None) def slot_roots(self, imports=True, mixins=True) -> list[SlotDefinitionName]: @@ -1016,9 +1064,9 @@ def slot_roots(self, imports=True, mixins=True) -> list[SlotDefinitionName]: :param mixins: :return: """ - return [c - for c in self.all_slots(imports=imports) - if self.slot_parents(c, mixins=mixins, imports=imports) == []] + return [ + c for c in self.all_slots(imports=imports) if self.slot_parents(c, mixins=mixins, imports=imports) == [] + ] @lru_cache(None) def slot_leaves(self, imports=True, mixins=True) -> list[SlotDefinitionName]: @@ -1028,9 +1076,9 @@ def slot_leaves(self, imports=True, mixins=True) -> list[SlotDefinitionName]: :param mixins: :return: """ - return [c - for c in self.all_slots(imports=imports) - if self.slot_children(c, mixins=mixins, imports=imports) == []] + return [ + c for c in self.all_slots(imports=imports) if self.slot_children(c, mixins=mixins, imports=imports) == [] + ] @lru_cache(None) def is_multivalued(self, slot_name: SlotDefinition) -> bool: @@ -1050,15 +1098,15 @@ def slot_is_true_for_metadata_property(self, slot_name: SlotDefinition, metadata will return True if the slot id has the identifier property set to True. :param slot_name: slot to test for multivalued - :param metadata_property: controlled vocabulary for boolean attribtues + :param metadata_property: controlled vocabulary for boolean attributes :return: boolean """ induced_slot = self.induced_slot(slot_name) - if type(getattr(induced_slot, metadata_property)) == bool: + if type(getattr(induced_slot, metadata_property)) is bool: return True if getattr(induced_slot, metadata_property) else False else: - raise ValueError(f'property to introspect must be of type "boolean"') + raise ValueError('property to introspect must be of type "boolean"') def get_element(self, element: Union[ElementName, Element], imports=True) -> Element: """ @@ -1081,7 +1129,9 @@ def get_element(self, element: Union[ElementName, Element], imports=True) -> Ele e = self.get_subset(element, imports=imports) return e - def get_uri(self, element: Union[ElementName, Element], imports=True, expand=False, native=False, use_element_type=False) -> str: + def get_uri( + self, element: Union[ElementName, Element], imports=True, expand=False, native=False, use_element_type=False + ) -> str: """ Return the CURIE or URI for a schema element. If the schema defines a specific URI, this is used, otherwise this is constructed from the default prefix combined with the element name @@ -1104,26 +1154,26 @@ def get_uri(self, element: Union[ElementName, Element], imports=True, expand=Fal uri = e.uri e_name = underscore(e.name) else: - raise ValueError(f'Must be class or slot or type: {e}') + raise ValueError(f"Must be class or slot or type: {e}") if uri is None or native: if e.from_schema is not None: schema = next((sc for sc in self.schema_map.values() if sc.id == e.from_schema), None) if schema is None: - raise ValueError(f'Cannot find {e.from_schema} in schema_map') + raise ValueError(f"Cannot find {e.from_schema} in schema_map") else: schema = self.schema_map[self.in_schema(e.name)] if use_element_type: - e_type = e.class_name.split("_",1)[0] # for example "class_definition" - e_type_path = f"{e_type}/" + e_type = e.class_name.split("_", 1)[0] # for example "class_definition" + e_type_path = f"{e_type}/" else: e_type_path = "" pfx = schema.default_prefix - # To construct the uri we have to find out if the schema has a default_prefix + # To construct the uri we have to find out if the schema has a default_prefix # or if a pseudo "prefix" was derived from the schema id. if pfx == sfx(str(schema.id)): # no prefix defined in schema - uri = f'{pfx}{e_type_path}{e_name}' + uri = f"{pfx}{e_type_path}{e_name}" else: - uri = f'{pfx}:{e_type_path}{e_name}' + uri = f"{pfx}:{e_type_path}{e_name}" if expand: return self.expand_curie(uri) else: @@ -1135,8 +1185,8 @@ def expand_curie(self, uri: str) -> str: :param uri: :return: URI as a string """ - if ':' in uri: - parts = uri.split(':') + if ":" in uri: + parts = uri.split(":") if len(parts) == 2: [pfx, local_id] = parts ns = self.namespaces() @@ -1156,8 +1206,10 @@ def get_elements_applicable_by_identifier(self, identifier: str) -> list[str]: """ elements = self.get_elements_applicable_by_prefix(self.namespaces().prefix_for(identifier)) if len(elements) == 0: - logger.warning("no element found for the given curie using id_prefixes attribute" - ": %s, try get_mappings method?", identifier) + logger.warning( + "no element found for the given curie using id_prefixes attribute" ": %s, try get_mappings method?", + identifier, + ) return elements @lru_cache(CACHE_SIZE) @@ -1173,7 +1225,7 @@ def get_elements_applicable_by_prefix(self, prefix: str) -> list[str]: applicable_elements = [] elements = self.all_elements() for category, category_element in elements.items(): - if hasattr(category_element, 'id_prefixes') and prefix in category_element.id_prefixes: + if hasattr(category_element, "id_prefixes") and prefix in category_element.id_prefixes: applicable_elements.append(category_element.name) return applicable_elements @@ -1200,8 +1252,9 @@ def all_aliases(self) -> list[str]: return element_aliases @lru_cache(None) - def get_mappings(self, element_name: ElementName = None, imports=True, expand=False) -> dict[ - MAPPING_TYPE, list[URIorCURIE]]: + def get_mappings( + self, element_name: ElementName = None, imports=True, expand=False + ) -> dict[MAPPING_TYPE, list[URIorCURIE]]: """ Get all mappings for a given element @@ -1213,14 +1266,14 @@ def get_mappings(self, element_name: ElementName = None, imports=True, expand=Fa e = self.get_element(element_name, imports=imports) if isinstance(e, ClassDefinition) or isinstance(e, SlotDefinition) or isinstance(e, TypeDefinition): m_dict = { - 'self': [self.get_uri(element_name, imports=imports, expand=False)], - 'native': [self.get_uri(element_name, imports=imports, expand=False, native=True)], - 'exact': e.exact_mappings, - 'narrow': e.narrow_mappings, - 'broad': e.broad_mappings, - 'related': e.related_mappings, - 'close': e.close_mappings, - 'undefined': e.mappings + "self": [self.get_uri(element_name, imports=imports, expand=False)], + "native": [self.get_uri(element_name, imports=imports, expand=False, native=True)], + "exact": e.exact_mappings, + "narrow": e.narrow_mappings, + "broad": e.broad_mappings, + "related": e.related_mappings, + "close": e.close_mappings, + "undefined": e.mappings, } else: m_dict = {} @@ -1267,7 +1320,9 @@ def get_element_by_mapping(self, mapping_id: URIorCURIE) -> list[str]: elements = self.all_elements() for el in elements: element = self.get_element(el) - mappings = element.exact_mappings + element.close_mappings + element.narrow_mappings + element.broad_mappings + mappings = ( + element.exact_mappings + element.close_mappings + element.narrow_mappings + element.broad_mappings + ) if mapping_id in mappings: model_elements.append(element.name) return model_elements @@ -1297,7 +1352,7 @@ def is_relationship(self, class_name: CLASS_NAME = None, imports=True) -> bool: :param imports: :return: true if the class represents a relationship """ - STMT_TYPES = ['rdf:Statement', 'owl:Axiom'] + STMT_TYPES = ["rdf:Statement", "owl:Axiom"] for an in self.class_ancestors(class_name, imports=imports): if self.get_uri(an) in STMT_TYPES: return True @@ -1324,8 +1379,9 @@ def annotation_dict(self, element_name: ElementName, imports=True) -> dict[URIor return {k: v.value for k, v in e.annotations.items()} @lru_cache(None) - def class_slots(self, class_name: CLASS_NAME, imports=True, direct=False, attributes=True) -> list[ - SlotDefinitionName]: + def class_slots( + self, class_name: CLASS_NAME, imports=True, direct=False, attributes=True + ) -> list[SlotDefinitionName]: """ :param class_name: :param imports: include imports closure @@ -1350,8 +1406,9 @@ def class_slots(self, class_name: CLASS_NAME, imports=True, direct=False, attrib return slots_nr @lru_cache(None) - def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, imports=True, - mangle_name=False) -> SlotDefinition: + def induced_slot( + self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, imports=True, mangle_name=False + ) -> SlotDefinition: """ Given a slot, in the context of a particular class, yield a dynamic SlotDefinition that has all properties materialized. @@ -1386,8 +1443,10 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo slot = self.get_slot(slot_name, imports, attributes=True) if slot is None: - raise ValueError(f"No such slot {slot_name} as an attribute of {class_name} ancestors " - "or as a slot definition in the schema") + raise ValueError( + f"No such slot {slot_name} as an attribute of {class_name} ancestors " + "or as a slot definition in the schema" + ) # copy the slot, as it will be modified induced_slot = copy(slot) @@ -1400,8 +1459,8 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo if getattr(anc_slot, metaslot_name, None): setattr(induced_slot, metaslot_name, copy(getattr(anc_slot, metaslot_name))) COMBINE = { - 'maximum_value': lambda x, y: min(x, y), - 'minimum_value': lambda x, y: max(x, y), + "maximum_value": lambda x, y: min(x, y), + "minimum_value": lambda x, y: max(x, y), } # iterate through all metaslots, and potentially populate metaslot value for induced slot for metaslot_name in self._metaslots_for_slot(): @@ -1433,9 +1492,9 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo # ) if not is_empty(v2): v = v2 - logger.debug(f'{v} takes precedence over {v2} for {induced_slot.name}.{metaslot_name}') + logger.debug(f"{v} takes precedence over {v2} for {induced_slot.name}.{metaslot_name}") if v is None: - if metaslot_name == 'range': + if metaslot_name == "range": v = self.schema.default_range if v is not None: setattr(induced_slot, metaslot_name, v) @@ -1444,7 +1503,7 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo if slot.identifier or slot.key: slot.required = True if mangle_name: - mangled_name = f'{camelcase(class_name)}__{underscore(slot_name)}' + mangled_name = f"{camelcase(class_name)}__{underscore(slot_name)}" induced_slot.name = mangled_name if not induced_slot.alias: induced_slot.alias = underscore(slot_name) @@ -1456,7 +1515,7 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo @lru_cache(None) def _metaslots_for_slot(self): - fake_slot = SlotDefinition('__FAKE') + fake_slot = SlotDefinition("__FAKE") return vars(fake_slot).keys() @lru_cache(None) @@ -1608,14 +1667,14 @@ def slot_applicable_range_elements(self, slot: SlotDefinition) -> list[ClassDefi if r in self.all_classes(): range_types.append(ClassDefinition.class_name) rc = self.get_class(r) - if rc.class_uri == 'linkml:Any': + if rc.class_uri == "linkml:Any": is_any = True if is_any or r in self.all_enums(): range_types.append(EnumDefinition.class_name) if is_any or r in self.all_types(): range_types.append(TypeDefinition.class_name) if not range_types: - raise ValueError(f'Unrecognized range: {r}') + raise ValueError(f"Unrecognized range: {r}") return range_types def slot_range_as_union(self, slot: SlotDefinition) -> list[ElementName]: @@ -1635,9 +1694,7 @@ def slot_range_as_union(self, slot: SlotDefinition) -> list[ElementName]: range_union_of.append(x.range) return range_union_of - def get_classes_by_slot( - self, slot: SlotDefinition, include_induced: bool = False - ) -> list[ClassDefinitionName]: + def get_classes_by_slot(self, slot: SlotDefinition, include_induced: bool = False) -> list[ClassDefinitionName]: """Get all classes that use a given slot, either as a direct or induced slot. :param slot: slot in consideration @@ -1653,9 +1710,7 @@ def get_classes_by_slot( if include_induced: for c_name in all_classes: - induced_slot_names = [ - ind_slot.name for ind_slot in self.class_induced_slots(c_name) - ] + induced_slot_names = [ind_slot.name for ind_slot in self.class_induced_slots(c_name)] if slot.name in induced_slot_names: classes_set.add(c_name) @@ -1666,7 +1721,7 @@ def get_slots_by_enum(self, enum_name: ENUM_NAME = None) -> list[SlotDefinition] """Get all slots that use a given enum: schema defined, attribute, or slot_usage. :param enum_name: enum in consideration - :return: list of slots, either schem or both class attribute defined + :return: list of slots, either schema or both class attribute defined """ enum_slots = [] for s in self.all_slots().values(): @@ -1719,7 +1774,7 @@ def usage_index(self) -> dict[ElementName, list[SchemaUsage]]: :return: dictionary of SchemaUsages keyed by used elements """ - ROLES = ['domain', 'range', 'any_of', 'exactly_one_of', 'none_of', 'all_of'] + ROLES = ["domain", "range", "any_of", "exactly_one_of", "none_of", "all_of"] ix = defaultdict(list) for cn, c in self.all_classes().items(): direct_slots = c.slots @@ -1891,8 +1946,8 @@ def set_modified(self) -> None: self.modifications += 1 def materialize_patterns(self) -> None: - """Materialize schema by expanding structured patterns - into regular expressions based on composite patterns + """Materialize schema by expanding structured patterns + into regular expressions based on composite patterns provided in the settings dictionary. """ resolver = PatternResolver(self) @@ -1916,7 +1971,7 @@ def materialize_pattern_into_slot_definition(slot_definition: SlotDefinition) -> materialize_pattern_into_slot_definition(slot_definition) def materialize_derived_schema(self) -> SchemaDefinition: - """ Materialize a schema view into a schema definition """ + """Materialize a schema view into a schema definition""" derived_schema = deepcopy(self.schema) derived_schemaview = SchemaView(derived_schema) derived_schemaview.merge_imports() diff --git a/linkml_runtime/utils/schemaview_cli.py b/linkml_runtime/utils/schemaview_cli.py index 44256451..16454124 100644 --- a/linkml_runtime/utils/schemaview_cli.py +++ b/linkml_runtime/utils/schemaview_cli.py @@ -1,41 +1,31 @@ +import builtins import io import json import logging +import click from json_flattener import flatten_to_csv +from linkml_runtime.dumpers import json_dumper, yaml_dumper from linkml_runtime.linkml_model import Element from linkml_runtime.utils.schemaview import SchemaView -from linkml_runtime.dumpers import json_dumper, yaml_dumper -import click -import builtins logger = logging.getLogger(__name__) -DEFAULT_DISPLAY_COLS = [ - 'name', - 'is_a', - 'description', - 'owner' -] +DEFAULT_DISPLAY_COLS = ["name", "is_a", "description", "owner"] -schema_option = click.option( - "-s", "--schema", help="Path to schema in LinkML yaml." -) +schema_option = click.option("-s", "--schema", help="Path to schema in LinkML yaml.") columns_option = click.option( - "-c", "--columns", - default=','.join(DEFAULT_DISPLAY_COLS), - help="Comma separate list of columns to display." + "-c", "--columns", default=",".join(DEFAULT_DISPLAY_COLS), help="Comma separate list of columns to display." ) + @click.group() @click.option("-v", "--verbose", count=True) @click.option("-q", "--quiet") def main(verbose: int, quiet: bool): - """Main - - """ + """Main""" if verbose >= 2: logging.basicConfig(level=logging.DEBUG) elif verbose == 1: @@ -49,7 +39,7 @@ def main(verbose: int, quiet: bool): @main.command() @schema_option @columns_option -@click.option('-t', '--element-type', help='Element type') +@click.option("-t", "--element-type", help="Element type") def list(schema, columns, element_type): """List elements in schema @@ -58,18 +48,19 @@ def list(schema, columns, element_type): """ schema_view = SchemaView(schema) - logger.info(f'id={schema_view.schema.id}') - logger.info(f'name={schema_view.schema.name}') + logger.info(f"id={schema_view.schema.id}") + logger.info(f"name={schema_view.schema.name}") enames = schema_view.all_element() elements = [schema_view.get_element(ename) for ename in enames] if element_type is not None: elements = [e for e in elements if element_type in type(e).class_name] _show_elements(elements, columns=columns) + @main.command() @schema_option @columns_option -@click.argument('class_names', nargs=-1) +@click.argument("class_names", nargs=-1) def islot(schema, columns, class_names): """Show induced slots for a list of classes @@ -79,15 +70,16 @@ def islot(schema, columns, class_names): """ schema_view = SchemaView(schema) for cn in class_names: - logger.info(f'Class: {cn}') + logger.info(f"Class: {cn}") islots = schema_view.class_induced_slots(cn) _show_elements(islots, columns=columns) + @main.command() @schema_option -@click.option('--is-a/--no-is-a', default=True, help='Include is_a') -@click.option('--mixins/--no-mixins', default=True, help='Include mixins') -@click.argument('class_names', nargs=-1) +@click.option("--is-a/--no-is-a", default=True, help="Include is_a") +@click.option("--mixins/--no-mixins", default=True, help="Include mixins") +@click.argument("class_names", nargs=-1) def ancs(schema, class_names, is_a, mixins): """Show ancestors for classes @@ -97,16 +89,17 @@ def ancs(schema, class_names, is_a, mixins): """ schema_view = SchemaView(schema) for cn in class_names: - logger.info(f'Class: {cn}') + logger.info(f"Class: {cn}") ancs = schema_view.class_ancestors(cn, is_a=is_a, mixins=mixins) for a in ancs: - print(f'{cn}\t{a}') + print(f"{cn}\t{a}") + @main.command() @schema_option -@click.option('--is-a/--no-is-a', default=True, help='Include is_a') -@click.option('--mixins/--no-mixins', default=True, help='Include mixins') -@click.argument('class_names', nargs=-1) +@click.option("--is-a/--no-is-a", default=True, help="Include is_a") +@click.option("--mixins/--no-mixins", default=True, help="Include mixins") +@click.argument("class_names", nargs=-1) def descs(schema, class_names, is_a, mixins): """Show descendants for classes @@ -116,35 +109,37 @@ def descs(schema, class_names, is_a, mixins): """ schema_view = SchemaView(schema) for cn in class_names: - logger.info(f'Class: {cn}') + logger.info(f"Class: {cn}") ds = schema_view.class_descendants(cn, is_a=is_a, mixins=mixins) for d in ds: - print(f'{cn}\t{d}') + print(f"{cn}\t{d}") + @main.command() @schema_option -@click.argument('class_names', nargs=-1) +@click.argument("class_names", nargs=-1) def delete(schema, class_names): - """Deletes classes - - """ + """Deletes classes""" schema_view = SchemaView(schema) for cn in class_names: - logger.info(f'Class: {cn}') + logger.info(f"Class: {cn}") schema_view.delete_class(cn) print(yaml_dumper.dumps(schema_view.schema)) -def _show_elements(elements: builtins.list[Element], columns=None, output = io.StringIO()) -> None: +def _show_elements(elements: builtins.list[Element], columns=None, output=io.StringIO()) -> None: elements_j = json.loads(json_dumper.dumps(elements, inject_type=False)) - if columns is not None and columns != '' and columns != [] and columns != '%': + if columns is not None and columns != "" and columns != [] and columns != "%": if isinstance(columns, str): - columns = columns.split(',') + columns = columns.split(",") + def filter_columns(row: dict): return {k: row.get(k, None) for k in columns} + elements_j = [filter_columns(e) for e in elements_j] flatten_to_csv(elements_j, output) print(output.getvalue()) + if __name__ == "__main__": main() diff --git a/linkml_runtime/utils/slot.py b/linkml_runtime/utils/slot.py index 82adbf40..a09e4344 100644 --- a/linkml_runtime/utils/slot.py +++ b/linkml_runtime/utils/slot.py @@ -1,13 +1,14 @@ from dataclasses import dataclass -from typing import Optional, Any from re import Pattern +from typing import Any, Optional from rdflib import URIRef @dataclass class Slot: - """ Runtime slot definition """ + """Runtime slot definition""" + uri: URIRef name: str curie: Optional[str] diff --git a/linkml_runtime/utils/strictness.py b/linkml_runtime/utils/strictness.py index 6d129bf4..298bb4a4 100644 --- a/linkml_runtime/utils/strictness.py +++ b/linkml_runtime/utils/strictness.py @@ -1,7 +1,6 @@ - - class BOOL: - """ Boolean container -- supports global boolean variables """ + """Boolean container -- supports global boolean variables""" + def __init__(self, v: bool) -> None: self.v = v @@ -16,19 +15,19 @@ def __str__(self): def strict() -> bool: - """ Switch to global strict mode """ + """Switch to global strict mode""" rval = GLOBAL_STRICT.v GLOBAL_STRICT.v = True return rval def lax() -> bool: - """ Switch to global lax mode """ + """Switch to global lax mode""" rval = GLOBAL_STRICT.v GLOBAL_STRICT.v = False return rval def is_strict() -> bool: - """ Return the global strictness setting """ + """Return the global strictness setting""" return bool(GLOBAL_STRICT) diff --git a/linkml_runtime/utils/uri_validator.py b/linkml_runtime/utils/uri_validator.py index f761415d..b9d12386 100644 --- a/linkml_runtime/utils/uri_validator.py +++ b/linkml_runtime/utils/uri_validator.py @@ -157,7 +157,7 @@ # # authority = [ userinfo "@" ] host [ ":" port ] -#authority = rf"""(?: (?P {userinfo} ) @)? +# authority = rf"""(?: (?P {userinfo} ) @)? authority = rf"""(?P (?: {userinfo} @)? {host} @@ -326,7 +326,7 @@ uri_validator = re.compile(f"^{URI}$", re.VERBOSE) -#uri_ref_validator = re.compile(f"^{URI_reference}$", re.VERBOSE) +# uri_ref_validator = re.compile(f"^{URI_reference}$", re.VERBOSE) uri_relative_ref_validator = re.compile(f"^{relative_ref}$", re.VERBOSE) @@ -358,4 +358,3 @@ def validate_uri_reference(input): def validate_curie(input): return curie_validator.match(input) - diff --git a/linkml_runtime/utils/walker_utils.py b/linkml_runtime/utils/walker_utils.py index 1aa0061c..ebebed63 100644 --- a/linkml_runtime/utils/walker_utils.py +++ b/linkml_runtime/utils/walker_utils.py @@ -3,7 +3,7 @@ """ from copy import deepcopy -from typing import Callable, Union, Any +from typing import Any, Callable, Union from linkml_runtime.utils.yamlutils import YAMLRoot @@ -21,8 +21,7 @@ def traverse_object_tree(obj: YAMLRoot, func: Callable, mutate: bool = True) -> # implementation for traverse_object_tree, but also accepts lists, dicts -def _traverse_object_tree_1(obj: Union[YAMLRoot, list, dict], func: Callable, - mutate: bool = True) -> Any: +def _traverse_object_tree_1(obj: Union[YAMLRoot, list, dict], func: Callable, mutate: bool = True) -> Any: if isinstance(obj, list): return [_traverse_object_tree_1(x, func, mutate) for x in obj] elif isinstance(obj, dict): diff --git a/linkml_runtime/utils/yamlutils.py b/linkml_runtime/utils/yamlutils.py index 8ca8b309..b151ede8 100644 --- a/linkml_runtime/utils/yamlutils.py +++ b/linkml_runtime/utils/yamlutils.py @@ -1,18 +1,18 @@ +import re +import textwrap from copy import copy from json import JSONDecoder -from typing import Union, Any, Optional, Callable from pprint import pformat -import textwrap -import re +from typing import Any, Callable, Optional, Union import yaml from deprecated.classic import deprecated -from jsonasobj2 import JsonObj, as_json, as_dict, JsonObjTypes, items +from jsonasobj2 import JsonObj, JsonObjTypes, as_dict, as_json, items from rdflib import Graph, URIRef from yaml.constructor import ConstructorError from linkml_runtime.utils.context_utils import CONTEXTS_PARAM_TYPE, merge_contexts -from linkml_runtime.utils.formatutils import is_empty, items +from linkml_runtime.utils.formatutils import is_empty YAMLObjTypes = Union[JsonObjTypes, "YAMLRoot"] @@ -25,29 +25,30 @@ class YAMLMark(yaml.error.Mark): def __str__(self): snippet = self.get_snippet() - where = f"\nFile \"{self.name}\", line {self.line+1}, column {self.column+1}" + where = f'\nFile "{self.name}", line {self.line+1}, column {self.column+1}' if snippet is not None: - where += ":\n"+snippet + where += ":\n" + snippet return where + class YAMLRoot(JsonObj): """ The root object for all python YAML representations """ - def __post_init__(self, *args: list[str], **kwargs): + def __post_init__(self, *args: list[str], **kwargs): if args or kwargs: messages: list[str] = [] for v in args: - v = repr(v)[:40].replace('\n', '\\n') + v = repr(v)[:40].replace("\n", "\\n") messages.append(f"Unknown positional argument: {v}") for k in kwargs.keys(): - v = repr(kwargs[k])[:40].replace('\n', '\\n') + v = repr(kwargs[k])[:40].replace("\n", "\\n") messages.append(f"{TypedNode.yaml_loc(k)} Unknown argument: {k} = {v}") - raise ValueError('\n'.join(messages)) + raise ValueError("\n".join(messages)) def _default(self, obj, filtr: Callable[[dict], dict] = None): - """ JSON serializer callback. + """JSON serializer callback. 1) Filter out empty values (None, {}, [] and False) and mangle the names 2) Add ID entries for dictionary entries @@ -62,10 +63,15 @@ def _default(self, obj, filtr: Callable[[dict], dict] = None): is_classvar = k.startswith("type_") and hasattr(type(obj), k) if is_classvar: print(f"***** {k} is classvar ") - if not is_classvar and not k.startswith('_') and v is not None and\ - (not isinstance(v, (dict, list, bool)) or v): + if ( + not is_classvar + and not k.startswith("_") + and v is not None + and (not isinstance(v, (dict, list, bool)) or v) + ): from linkml_runtime.utils.enumerations import EnumDefinitionImpl + if isinstance(v, dict): itemslist = [] for vk, vv in v.items(): @@ -84,8 +90,9 @@ def _default(self, obj, filtr: Callable[[dict], dict] = None): rval[k] = v return rval else: - return obj._default(obj) if hasattr(obj, '_default') and callable(obj._default) else\ - JSONDecoder().decode(obj) + return ( + obj._default(obj) if hasattr(obj, "_default") and callable(obj._default) else JSONDecoder().decode(obj) + ) @staticmethod def _is_empty(v: Any) -> bool: @@ -98,8 +105,7 @@ def _normalize_inlined_as_list(self, slot_name: str, slot_type: type, key_name: def _normalize_inlined_as_dict(self, slot_name: str, slot_type: type, key_name: str, keyed: bool) -> None: self._normalize_inlined(slot_name, slot_type, key_name, keyed, False) - def _normalize_inlined(self, slot_name: str, slot_type: type, key_name: str, keyed: bool, is_list: bool) \ - -> None: + def _normalize_inlined(self, slot_name: str, slot_type: type, key_name: str, keyed: bool, is_list: bool) -> None: """ __post_init__ function for a list of inlined keyed or identified classes. @@ -121,11 +127,12 @@ def _normalize_inlined(self, slot_name: str, slot_type: type, key_name: str, key cooked_keys = set() def order_up(key: Any, cooked_entry: YAMLRoot) -> None: - """ A cooked entry is ready to be added to the return slot """ + """A cooked entry is ready to be added to the return slot""" if cooked_entry[key_name] != key: raise ValueError( - f"Slot: {loc(slot_name)} - attribute {loc(key_name)} " \ - f"value ({loc(cooked_entry[key_name])}) does not match key ({loc(key)})") + f"Slot: {loc(slot_name)} - attribute {loc(key_name)} " + f"value ({loc(cooked_entry[key_name])}) does not match key ({loc(key)})" + ) if keyed and key in cooked_keys: raise ValueError(f"{loc(key)}: duplicate key") cooked_keys.add(key) @@ -135,13 +142,13 @@ def order_up(key: Any, cooked_entry: YAMLRoot) -> None: cooked_slot[key] = cooked_entry def loc(s): - loc_str = TypedNode.yaml_loc(s) if isinstance(s, TypedNode) else '' - if loc_str == ': ': - loc_str = '' + loc_str = TypedNode.yaml_loc(s) if isinstance(s, TypedNode) else "" + if loc_str == ": ": + loc_str = "" return loc_str + str(s) def form_1(entries: dict[Any, Optional[Union[dict, JsonObj]]]) -> None: - """ A dictionary of key:dict entries where key is the identifier and dict is an instance of slot_type """ + """A dictionary of key:dict entries where key is the identifier and dict is an instance of slot_type""" for key, raw_obj in items(entries): if raw_obj is None: raw_obj = {} @@ -170,7 +177,7 @@ def form_1(entries: dict[Any, Optional[Union[dict, JsonObj]]]) -> None: if lek == key_name and not isinstance(lev, (list, dict, JsonObj)): # key_name:value order_up(list_entry[lek], slot_type(list_entry)) - break # Not strictly necessary, but + break # Not strictly necessary, but elif not isinstance(lev, (list, dict, JsonObj)): # key: value --> slot_type(key, value) order_up(lek, slot_type(lek, lev)) @@ -189,8 +196,11 @@ def form_1(entries: dict[Any, Optional[Union[dict, JsonObj]]]) -> None: order_up(list_entry, slot_type(**{key_name: list_entry})) else: # We have a dictionary - if key_name in raw_slot and raw_slot[key_name] is not None \ - and not isinstance(raw_slot[key_name], (list, dict, JsonObj)): + if ( + key_name in raw_slot + and raw_slot[key_name] is not None + and not isinstance(raw_slot[key_name], (list, dict, JsonObj)) + ): # Vanilla dictionary - {key: v11, s12: v12, ...} order_up(raw_slot[key_name], slot_type(**as_dict(raw_slot))) else: @@ -208,8 +218,9 @@ def form_1(entries: dict[Any, Optional[Union[dict, JsonObj]]]) -> None: raise ValueError(f"Unrecognized entry: {loc(k)}: {str(v)}") self[slot_name] = cooked_slot - def _normalize_inlined_slot(self, slot_name: str, slot_type: type, key_name: Optional[str], - inlined_as_list: Optional[bool], keyed: bool) -> None: + def _normalize_inlined_slot( + self, slot_name: str, slot_type: type, key_name: Optional[str], inlined_as_list: Optional[bool], keyed: bool + ) -> None: """ A deprecated entry point to slot normalization. Used for models generated prior to the linkml-runtime split. @@ -218,16 +229,28 @@ def _normalize_inlined_slot(self, slot_name: str, slot_type: type, key_name: Opt self. = [] if not isinstance(self., list): self.extensions = [self.] - self._normalize_inlined_slot(slot_name="", slot_type=, key_name="", inlined_as_list=True, keyed=...) + self._normalize_inlined_slot( + slot_name="", + slot_type=, + key_name="", + inlined_as_list=True, + keyed=... + ) or if self. is None: self. = [] if not isinstance(self., (list, dict)): self.local_names = [self.] - self._normalize_inlined_slot(slot_name="", slot_type=, key_name="", inlined_as_list=None, keyed=...) + self._normalize_inlined_slot( + slot_name="", + slot_type=, + key_name="", + inlined_as_list=None, + keyed=... + ) - The above pattern broke when the new jsonasobj was introduced, which is why we have the normalization above. The code - below reverse engineers the above and invokes the new form + The above pattern broke when the new jsonasobj was introduced, which is why we have the normalization above. + The code below reverse engineers the above and invokes the new form """ if inlined_as_list: @@ -244,7 +267,7 @@ def _normalize_inlined_slot(self, slot_name: str, slot_type: type, key_name: Opt @classmethod def _class_for(cls, attribute: str, uri_or_curie: Union[str, URIRef]) -> Optional[type["YAMLRoot"]]: - """ Locate self or descendant class that has attribute == uri_or_curie """ + """Locate self or descendant class that has attribute == uri_or_curie""" if getattr(cls, attribute, None) == uri_or_curie: return cls for subclass in cls.__subclasses__(): @@ -258,17 +281,17 @@ def _class_for_uri(cls: type["YAMLRoot"], uri: str, use_model_uri: bool = False) """ Return the self or descendant of self having with a matching class uri """ - return cls._class_for('class_model_uri' if use_model_uri else 'class_class_uri', URIRef(uri)) + return cls._class_for("class_model_uri" if use_model_uri else "class_class_uri", URIRef(uri)) @classmethod def _class_for_curie(cls: type["YAMLRoot"], curie: str) -> Optional[type["YAMLRoot"]]: - return cls._class_for('class_class_curie', curie) + return cls._class_for("class_class_curie", curie) # ================== # Error intercepts # ================== def MissingRequiredField(self, field_name: str) -> None: - """ Generic loader error handler """ + """Generic loader error handler""" raise ValueError(f"{field_name} must be supplied") def __repr__(self): @@ -277,7 +300,8 @@ def __repr__(self): def __str__(self): return repr(self) -def _pformat(fields:dict, cls_name:str, indent:str = ' ') -> str: + +def _pformat(fields: dict, cls_name: str, indent: str = " ") -> str: """ pretty format the fields of the items of a ``YAMLRoot`` object without the wonky indentation of pformat. see ``YAMLRoot.__repr__``. @@ -293,8 +317,9 @@ def _pformat(fields:dict, cls_name:str, indent:str = ' ') -> str: # pformat handles everything else that isn't a YAMLRoot object, but it sure does look ugly # use it to split lines and as the thing of last resort, but otherwise indent = 0, we'll do that val_str = pformat(val, indent=0, compact=True, sort_dicts=False) - # now we indent everything except the first line by indenting and then using regex to remove just the first indent - val_str = re.sub(rf'\A{re.escape(indent)}', '', textwrap.indent(val_str, indent)) + # now we indent everything except the first line by indenting + # and then using regex to remove just the first indent + val_str = re.sub(rf"\A{re.escape(indent)}", "", textwrap.indent(val_str, indent)) # now recombine with the key in a format that can be re-eval'd into an object if indent is just whitespace val_str = f"'{key}': " + val_str @@ -303,18 +328,18 @@ def _pformat(fields:dict, cls_name:str, indent:str = ' ') -> str: res.append(val_str) if total_len > 80: - inside = ',\n'.join(res) + inside = ",\n".join(res) # we indent twice - once for the inner contents of every inner object, and one to # offset from the root element. that keeps us from needing to be recursive except for the # single pformat call inside = textwrap.indent(inside, indent) - return cls_name + '({\n' + inside + '\n})' + return cls_name + "({\n" + inside + "\n})" else: - return cls_name + '({' + ', '.join(res) + '})' + return cls_name + "({" + ", ".join(res) + "})" def root_representer(dumper: yaml.Dumper, data: YAMLRoot): - """ YAML callback -- used to filter out empty values (None, {}, [] and false) + """YAML callback -- used to filter out empty values (None, {}, [] and false) @param dumper: data dumper @param data: data to be dumped @@ -323,11 +348,12 @@ def root_representer(dumper: yaml.Dumper, data: YAMLRoot): # TODO: Figure out how to import EnumDefinition here # elif isinstance(v, EnumDefinition): from linkml_runtime.utils.enumerations import EnumDefinitionImpl + if isinstance(data, EnumDefinitionImpl): data = data.code rval = dict() for k, v in data.__dict__.items(): - if not k.startswith('_') and v is not None and (not isinstance(v, (dict, list)) or v): + if not k.startswith("_") and v is not None and (not isinstance(v, (dict, list)) or v): rval[k] = v return dumper.represent_data(rval) @@ -348,7 +374,7 @@ def as_yaml(element: YAMLRoot) -> str: return yaml.dump(element, Dumper=yaml.SafeDumper, sort_keys=False) -def as_json_object(element: YAMLRoot, contexts: CONTEXTS_PARAM_TYPE = None, inject_type = True) -> JsonObj: +def as_json_object(element: YAMLRoot, contexts: CONTEXTS_PARAM_TYPE = None, inject_type=True) -> JsonObj: """ Return the representation of element as a JsonObj object :param element: element to return @@ -358,10 +384,10 @@ def as_json_object(element: YAMLRoot, contexts: CONTEXTS_PARAM_TYPE = None, inje """ rval = copy(element) if inject_type: - rval['@type'] = element.__class__.__name__ + rval["@type"] = element.__class__.__name__ context_element = merge_contexts(contexts) if context_element: - rval['@context'] = context_element['@context'] + rval["@context"] = context_element["@context"] return rval @@ -381,18 +407,21 @@ def loc(self) -> str: return self._loc() def _loc(self) -> str: - return f'File "{self._s.name}", line {self._s.line + 1}, col {self._s.column + 1}' if self._s else '' + return f'File "{self._s.name}", line {self._s.line + 1}, col {self._s.column + 1}' if self._s else "" @staticmethod def yaml_loc(loc_str: Optional[Union["TypedNode", str]] = None, suffix: Optional[str] = ": ") -> str: - """ Return the yaml file and location of loc_str if it exists """ - return '' if loc_str is None or not hasattr(loc_str, "_loc" or not callable(loc_str._loc)) else\ - (loc_str._loc() + suffix) + """Return the yaml file and location of loc_str if it exists""" + return ( + "" + if loc_str is None or not hasattr(loc_str, "_loc" or not callable(loc_str._loc)) + else (loc_str._loc() + suffix) + ) class extended_str(str, TypedNode): def concat(self, *items) -> "extended_str": - rval = extended_str(str(self) + ''.join([str(item) for item in items])) + rval = extended_str(str(self) + "".join([str(item) for item in items])) for item in items[::-1]: if isinstance(item, TypedNode): rval._s = item._s @@ -418,9 +447,9 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, DupCheckYamlLoader.map_constructor) self.add_constructor(yaml.resolver.BaseResolver.DEFAULT_SEQUENCE_TAG, DupCheckYamlLoader.seq_constructor) - self.add_constructor('tag:yaml.org,2002:str', DupCheckYamlLoader.construct_yaml_str) - self.add_constructor('tag:yaml.org,2002:int', DupCheckYamlLoader.construct_yaml_int) - self.add_constructor('tag:yaml.org,2002:float', DupCheckYamlLoader.construct_yaml_float) + self.add_constructor("tag:yaml.org,2002:str", DupCheckYamlLoader.construct_yaml_str) + self.add_constructor("tag:yaml.org,2002:int", DupCheckYamlLoader.construct_yaml_int) + self.add_constructor("tag:yaml.org,2002:float", DupCheckYamlLoader.construct_yaml_float) def get_mark(self): if self.stream is None: @@ -429,22 +458,20 @@ def get_mark(self): return YAMLMark(self.name, self.index, self.line, self.column, None, None) def construct_yaml_int(self, node): - """ Scalar constructor that returns the node information as the value """ + """Scalar constructor that returns the node information as the value""" return extended_int(super().construct_yaml_int(node)).add_node(node) def construct_yaml_str(self, node): - """ Scalar constructor that returns the node information as the value """ + """Scalar constructor that returns the node information as the value""" return extended_str(super().construct_yaml_str(node)).add_node(node) def construct_yaml_float(self, node): - """ Scalar constructor that returns the node information as the value """ + """Scalar constructor that returns the node information as the value""" return extended_float(super().construct_yaml_float(node)).add_node(node) @staticmethod - def map_constructor(loader, node, deep=False): - """ Duplicate of constructor.construct_mapping w/ exception that we check for dups - - """ + def map_constructor(loader, node, deep=False): + """Duplicate of constructor.construct_mapping w/ exception that we check for dups""" if not isinstance(node, yaml.MappingNode): raise ConstructorError(None, None, f"expected a mapping node, but found {node.id}", node.start_mark) mapping = {} @@ -452,21 +479,18 @@ def map_constructor(loader, node, deep=False): key = loader.construct_object(key_node, deep=deep) value = loader.construct_object(value_node, deep=deep) if key in mapping: - raise ValueError(f"Duplicate key: \"{key}\"") + raise ValueError(f'Duplicate key: "{key}"') mapping[key] = value return mapping @staticmethod def seq_constructor(loader, node, deep=False): if not isinstance(node, yaml.SequenceNode): - raise ConstructorError(None, None, - f"expected a sequence node, but found {node.id}", - node.start_mark) + raise ConstructorError(None, None, f"expected a sequence node, but found {node.id}", node.start_mark) for child in node.value: if not child.value: raise ConstructorError(None, None, "Empty list elements are not allowed", node.start_mark) - return [loader.construct_object(child, deep=deep) - for child in node.value] + return [loader.construct_object(child, deep=deep) for child in node.value] yaml.SafeDumper.add_multi_representer(YAMLRoot, root_representer) diff --git a/notebooks/SchemaView_Monarch.ipynb b/notebooks/SchemaView_Monarch.ipynb index ef527bcf..69988afc 100644 --- a/notebooks/SchemaView_Monarch.ipynb +++ b/notebooks/SchemaView_Monarch.ipynb @@ -18,8 +18,10 @@ "metadata": {}, "outputs": [], "source": [ + "import requests\n", + "\n", "from linkml_runtime.utils.schemaview import SchemaView\n", - "import requests \n", + "\n", "# note you can also use a path on a local filesystem\n", "view = SchemaView(\"https://raw.githubusercontent.com/biolink/biolink-model/master/biolink-model.yaml\")" ] @@ -90,7 +92,7 @@ "# object = 'phenotypic feature'\n", "object = 'sequence variant'\n", "\n", - "query_prefix = f'https://www.ebi.ac.uk/ols/api/ontologies/_ontology/terms/'\n", + "query_prefix = 'https://www.ebi.ac.uk/ols/api/ontologies/_ontology/terms/'\n", "mappings = view.get_mappings(object)\n", "if len(mappings) == 0:\n", " print(\"no exact mappings found for: \" + object)\n", diff --git a/poetry.lock b/poetry.lock index 8474ace3..1c75fa93 100644 --- a/poetry.lock +++ b/poetry.lock @@ -18,7 +18,7 @@ version = "25.3.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] files = [ {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, @@ -32,13 +32,60 @@ docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphi tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] +[[package]] +name = "black" +version = "24.10.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.9" +groups = ["lint"] +files = [ + {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, + {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, + {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, + {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, + {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, + {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, + {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, + {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, + {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, + {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, + {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, + {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, + {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, + {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, + {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, + {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, + {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, + {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, + {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, + {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, + {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, + {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.10)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "cattrs" version = "24.1.3" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["dev", "tests"] files = [ {file = "cattrs-24.1.3-py3-none-any.whl", hash = "sha256:adf957dddd26840f27ffbd060a6c4dd3b2192c5b7c2c0525ef1bd8131d8a83f5"}, {file = "cattrs-24.1.3.tar.gz", hash = "sha256:981a6ef05875b5bb0c7fb68885546186d306f10f0f6718fe9b96c226e68821ff"}, @@ -65,7 +112,7 @@ version = "2025.1.31" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] files = [ {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, @@ -77,7 +124,7 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -179,7 +226,7 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["main", "lint"] files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -188,18 +235,36 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "codespell" +version = "2.4.1" +description = "Fix common misspellings in text files" +optional = false +python-versions = ">=3.8" +groups = ["lint"] +files = [ + {file = "codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425"}, + {file = "codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5"}, +] + +[package.extras] +dev = ["Pygments", "build", "chardet", "pre-commit", "pytest", "pytest-cov", "pytest-dependency", "ruff", "tomli", "twine"] +hard-encoding-detection = ["chardet"] +toml = ["tomli ; python_version < \"3.11\""] +types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency"] + [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main"] -markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" +groups = ["main", "lint"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\"", lint = "platform_system == \"Windows\""} [[package]] name = "coverage" @@ -207,7 +272,7 @@ version = "6.5.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["dev", "tests"] files = [ {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, @@ -330,7 +395,7 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, @@ -358,7 +423,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -460,25 +525,49 @@ files = [ [package.dependencies] referencing = ">=0.31.0" +[[package]] +name = "mypy-extensions" +version = "1.1.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.8" +groups = ["lint"] +files = [ + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, +] + [[package]] name = "packaging" version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["main", "lint"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +groups = ["lint"] +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + [[package]] name = "platformdirs" version = "4.3.7" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["dev", "lint", "tests"] files = [ {file = "platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94"}, {file = "platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"}, @@ -733,6 +822,7 @@ optional = false python-versions = "*" groups = ["main"] files = [ + {file = "PyTrie-0.4.0-py3-none-any.whl", hash = "sha256:f687c224ee8c66cda8e8628a903011b692635ffbb08d4b39c5f92b18eb78c950"}, {file = "PyTrie-0.4.0.tar.gz", hash = "sha256:8f4488f402d3465993fb6b6efa09866849ed8cda7903b50647b7d0342b805379"}, ] @@ -848,7 +938,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -870,7 +960,7 @@ version = "1.2.1" description = "A persistent cache for python requests" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["dev", "tests"] files = [ {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, @@ -1019,6 +1109,34 @@ files = [ {file = "rpds_py-0.24.0.tar.gz", hash = "sha256:772cc1b2cd963e7e17e6cc55fe0371fb9c704d63e44cacec7b9b7f523b78919e"}, ] +[[package]] +name = "ruff" +version = "0.6.9" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +groups = ["lint"] +files = [ + {file = "ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd"}, + {file = "ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec"}, + {file = "ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039"}, + {file = "ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d"}, + {file = "ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117"}, + {file = "ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93"}, + {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"}, +] + [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1037,7 +1155,7 @@ version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["main", "lint"] markers = "python_version < \"3.11\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, @@ -1080,12 +1198,12 @@ version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] +groups = ["main", "dev", "lint", "tests"] files = [ {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, ] -markers = {dev = "python_version < \"3.11\""} +markers = {dev = "python_version < \"3.11\"", lint = "python_version < \"3.11\"", tests = "python_version < \"3.11\""} [[package]] name = "typing-inspection" @@ -1108,7 +1226,7 @@ version = "2.2.0" description = "URL normalization for Python" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["dev", "tests"] files = [ {file = "url_normalize-2.2.0-py3-none-any.whl", hash = "sha256:3fe387b62f5b66db94304bc703bf6d34de52aaa9590d4d1f1bbdf305a1430064"}, {file = "url_normalize-2.2.0.tar.gz", hash = "sha256:0f0b7cc95a95d2d9b0c9a51d47a326559bc05bd1558accdada21bb0c9504de85"}, @@ -1126,7 +1244,7 @@ version = "2.4.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" -groups = ["main", "dev"] +groups = ["main", "dev", "tests"] files = [ {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, @@ -1230,4 +1348,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = "^3.9" -content-hash = "a86079065945ae5cb39460f22b2a0d331f8145aeec49d25f05cb23b20ce0c468" +content-hash = "055ef9bf9d824156d24085e7dfb6d54cf36210f3516637aad4002b9b46579029" diff --git a/pyproject.toml b/pyproject.toml index d36d4d3e..1eab65b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,19 +75,64 @@ style = "pep440" coverage = "^6.2" requests-cache = "^1.2.0" +[tool.poetry.group.tests.dependencies] +coverage = "^6.2" +requests-cache = "^1.2.0" + +[tool.poetry.group.lint.dependencies] +ruff = "^0.6.9" +black = "^24.10.0" +codespell = "^2.3.0" + +[tool.black] +line-length = 120 +target-version = ["py39", "py310", "py311", "py312", "py313"] +force-exclude = ''' +/( + # default exclude + \.direnv|\.eggs|\.git|\.hg|\.ipynb_checkpoints|\.mypy_cache|\.nox|\.pytest_cache|\.ruff_cache|\.tox|\.svn|\.venv|\.vscode|__pypackages__|_build|buck-out|build|dist|venv + # additional exclude + | tests.*/output + | __snapshots__ + | docs + | examples + | notebooks +)/ +''' + [tool.ruff] line-length = 120 target-version = "py39" +force-exclude = true + +# -- Exclude files -- +extend-exclude = [ + "linkml_runtime/linkml_model/**/*.py", + "notebooks/**" +] [tool.ruff.lint] +# -- Rule selection -- select = [ - "F401", - "UP" + "E", # pycodestyle errors + "F", # Pyflakes + "I", # isort + "UP", # pyupgrade + "T100", # no debugger imports/usages ] -ignore = [ - # Until 3.9 is dropped - "UP007", +extend-ignore = [ + "E203", ] +pyupgrade.keep-runtime-typing = true # until we drop 3.9 [tool.ruff.lint.per-file-ignores] -"tests/**/*.py" = ["F401"] # unused imports +"tests/**/**.py" = ["F841", "E501", "F842", "E741"] # I ain't fixing all that + + +[tool.codespell] +skip = '.git,*.pdf,*.svg,./tests,pyproject.toml,*.dill,poetry.lock,*.ipynb,./linkml_runtime/linkml_model/*' +# Ignore table where words could be split across rows +# Ignore shortcut specifications like [Ff]alse +ignore-regex = '(\|.*\|.*\|.*\||\[[A-Z][a-z]\][a-z][a-z])' +ignore-words-list = 'mater,connexion,infarction,thirdparty' +quiet-level = 3 diff --git a/tests/__init__.py b/tests/__init__.py index 396a1754..19129def 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,10 +1,15 @@ -import logging import configparser +import logging + # Global testing control variables import os from tests.support.test_environment import MismatchAction +__all__ = [ + "MismatchAction", +] + # --------------------------------------------------------------- # DO NOT change this file. # To change the default test harness settings: @@ -15,31 +20,34 @@ # ---------------------------------------------------------------- config = configparser.ConfigParser() -config.read(os.path.join(os.path.dirname(__file__), 'test_config.ini')) -if 'test.settings' not in config.sections(): - config['test.settings'] = {} # initialize a blank setting if file doesn't exist -test_settings = config['test.settings'] +config.read(os.path.join(os.path.dirname(__file__), "test_config.ini")) +if "test.settings" not in config.sections(): + config["test.settings"] = {} # initialize a blank setting if file doesn't exist +test_settings = config["test.settings"] # Action on mismatch. One of 'Ignore', 'Report' or 'Fail' # If 'Fail', the expected file will be saved in the appropriate temp directory # NOTE: Before setting this back to Report or Ignore, you need to run cleartemp.sh in this directory -DEFAULT_MISMATCH_ACTION = eval(test_settings.get('DEFAULT_MISMATCH_ACTION', 'MismatchAction.Report')) +DEFAULT_MISMATCH_ACTION = eval(test_settings.get("DEFAULT_MISMATCH_ACTION", "MismatchAction.Report")) # Use local import map. If True, tests/input/local_import_map.json is used to create the test files. Note that this # will result in local path names being recorded in jsonld files. This should always be set to False before generating # the final output -USE_LOCAL_IMPORT_MAP = test_settings.getboolean('USE_LOCAL_IMPORT_MAP', False) +USE_LOCAL_IMPORT_MAP = test_settings.getboolean("USE_LOCAL_IMPORT_MAP", False) # There are lots of warnings emitted by the generators. Default logging level -DEFAULT_LOG_LEVEL = eval(test_settings.get('DEFAULT_LOG_LEVEL', 'logging.ERROR')) -DEFAULT_LOG_LEVEL_TEXT = test_settings.get('DEFAULT_LOG_LEVEL_TEXT', 'ERROR') +DEFAULT_LOG_LEVEL = getattr(logging, test_settings.get("DEFAULT_LOG_LEVEL", "WARNING")) +DEFAULT_LOG_LEVEL_TEXT = test_settings.get("DEFAULT_LOG_LEVEL_TEXT", "ERROR") # Skip RDF comparison, as it takes a lot of time -SKIP_RDF_COMPARE = test_settings.getboolean('SKIP_RDF_COMPARE', False) -SKIP_RDF_COMPARE_REASON = test_settings.get('SKIP_RDF_COMPARE_REASON', 'tests/__init__.py RDF output not checked SKIP_RDF_COMPARE is True') +SKIP_RDF_COMPARE = test_settings.getboolean("SKIP_RDF_COMPARE", False) +SKIP_RDF_COMPARE_REASON = test_settings.get( + "SKIP_RDF_COMPARE_REASON", "tests/__init__.py RDF output not checked SKIP_RDF_COMPARE is True" +) + # Exception for use in script testing. Global to prevent redefinition class CLIExitException(Exception): diff --git a/tests/conftest.py b/tests/conftest.py index f0f30ec9..faea77ef 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,9 @@ from pathlib import Path + import pytest import requests_cache + @pytest.fixture(scope="session", autouse=True) def patch_requests_cache(pytestconfig): """ @@ -19,4 +21,4 @@ def patch_requests_cache(pytestconfig): yield # If we want to delete cache, this is how we might do it! # if not pytestconfig.getoption("--with-output"): - # cache_file.unlink(missing_ok=True) \ No newline at end of file + # cache_file.unlink(missing_ok=True) diff --git a/tests/support/clicktestcase.py b/tests/support/clicktestcase.py index a35a35dc..9c3d958c 100644 --- a/tests/support/clicktestcase.py +++ b/tests/support/clicktestcase.py @@ -1,53 +1,54 @@ import os import shlex import unittest -from typing import Union, Optional, Callable +from typing import Callable, Optional, Union from warnings import warn -from tests.support.dirutils import make_and_clear_directory from tests.support.compare_rdf import compare_rdf -from tests.support.test_environment import TestEnvironmentTestCase, TestEnvironment +from tests.support.dirutils import make_and_clear_directory +from tests.support.test_environment import TestEnvironment, TestEnvironmentTestCase class ClickTestCase(TestEnvironmentTestCase): - """ Common tools for testing command line functions """ + """Common tools for testing command line functions""" + env: TestEnvironment = None # The variables below must be set by the inheriting class - testdir: str = None # subdirectory within outdir - click_ep = None # entry point for particular function - prog_name: str = None # executable name + testdir: str = None # subdirectory within outdir + click_ep = None # entry point for particular function + prog_name: str = None # executable name - test_base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'output')) - temp_base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'temp')) + test_base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "output")) + temp_base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "temp")) def source_file_path(self, *path: str) -> str: - """ Return the full file name of path in the input directory """ + """Return the full file name of path in the input directory""" return self.env.input_path(*path) def expected_file_path(self, *path: str) -> str: - """ Return the fill file path of the script subdirectory in the output directory """ + """Return the fill file path of the script subdirectory in the output directory""" return self.env.expected_path(self.testdir, *path) def temp_file_path(self, *path: str, is_dir: bool = False) -> str: - """ Create subdirectory in the temp directory to hold path """ + """Create subdirectory in the temp directory to hold path""" full_path = self.env.temp_file_path(self.testdir, *path) self.env.make_testing_directory(full_path if is_dir else os.path.dirname(full_path)) return full_path @staticmethod def jsonld_comparator(expected_data: str, actual_data: str) -> str: - """ Compare expected data in json-ld format to actual data in json-ld format """ + """Compare expected data in json-ld format to actual data in json-ld format""" return compare_rdf(expected_data, actual_data, "json-ld") @staticmethod def n3_comparator(expected_data: str, actual_data: str) -> str: - """ compare expected_data in n3 format to actual_data in n3 format """ + """compare expected_data in n3 format to actual_data in n3 format""" return compare_rdf(expected_data, actual_data, "n3") @staticmethod - def rdf_comparator(expected_data: str, actual_data: str, fmt: Optional[str] = 'turtle') -> str: - """ compare expected_data to actual_data using basic RDF comparator method """ + def rdf_comparator(expected_data: str, actual_data: str, fmt: Optional[str] = "turtle") -> str: + """compare expected_data to actual_data using basic RDF comparator method""" return compare_rdf(expected_data, actual_data, fmt=fmt) @staticmethod @@ -63,7 +64,7 @@ def always_pass_comparator(expected_data: str, new_data: str) -> Optional[str]: @staticmethod def closein_comparison(expected_txt: str, actual_txt: str) -> None: - """ Assist with testing comparison -- zero in on the first difference in a big string + """Assist with testing comparison -- zero in on the first difference in a big string @param expected_txt: @param actual_txt: @@ -79,22 +80,24 @@ def closein_comparison(expected_txt: str, actual_txt: str) -> None: offset += window nt = nt[window:] ot = ot[window:] - offset = max(offset-view, 0) + offset = max(offset - view, 0) print(" - - EXPECTED - -") - print(ow[offset:offset+view+view]) + print(ow[offset : offset + view + view]) print("\n - - ACTUAL - -") - print(nw[offset:offset+view+view]) - - def do_test(self, - args: Union[str, list[str]], - testFileOrDirectory: Optional[str] = None, - *, - expected_error: type(Exception) = None, - filtr: Optional[Callable[[str], str]] = None, - is_directory: bool = False, - add_yaml: bool = True, - comparator: Callable[[type(unittest.TestCase), str, str, str], str] = None, ) -> None: - """ Execute a command test + print(nw[offset : offset + view + view]) + + def do_test( + self, + args: Union[str, list[str]], + testFileOrDirectory: Optional[str] = None, + *, + expected_error: type(Exception) = None, + filtr: Optional[Callable[[str], str]] = None, + is_directory: bool = False, + add_yaml: bool = True, + comparator: Callable[[type(unittest.TestCase), str, str, str], str] = None, + ) -> None: + """Execute a command test @param args: Argument string or list to command. 'meta.yaml' is always supplied @param testFileOrDirectory: name of file or directory to record output in @@ -111,7 +114,7 @@ def do_test(self, if is_directory and (filtr or comparator): warn("filtr and comparator parameters aren't implemented for directory generation") - if add_yaml and (not arg_list or arg_list[0] != '--help'): + if add_yaml and (not arg_list or arg_list[0] != "--help"): raise NotImplementedError("This is an artifact from elsewhere") # arg_list.insert(0, self.env.meta_yaml) # arg_list += ["--importmap", self.env.import_map, "--log_level", DEFAULT_LOG_LEVEL_TEXT] @@ -121,15 +124,19 @@ def do_test(self, def do_gen(): if is_directory: - self.env.generate_directory(target, - lambda target_dir: self.click_ep(arg_list + ["-d", target_dir], - prog_name=self.prog_name, - standalone_mode=False)) + self.env.generate_directory( + target, + lambda target_dir: self.click_ep( + arg_list + ["-d", target_dir], prog_name=self.prog_name, standalone_mode=False + ), + ) else: - self.env.generate_single_file(target, - lambda: self.click_ep(arg_list, prog_name=self.prog_name, - standalone_mode=False), filtr=filtr, - comparator=comparator) + self.env.generate_single_file( + target, + lambda: self.click_ep(arg_list, prog_name=self.prog_name, standalone_mode=False), + filtr=filtr, + comparator=comparator, + ) if expected_error: with self.assertRaises(expected_error): @@ -152,5 +159,5 @@ def temp_directory(cls, base: str) -> str: return new_directory -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/support/compare_rdf.py b/tests/support/compare_rdf.py index 648dab5f..ea6118d7 100644 --- a/tests/support/compare_rdf.py +++ b/tests/support/compare_rdf.py @@ -1,10 +1,10 @@ import re from contextlib import redirect_stdout from io import StringIO -from typing import Union, Optional +from typing import Optional, Union -from rdflib import Graph, RDF -from rdflib.compare import to_isomorphic, IsomorphicGraph, graph_diff +from rdflib import RDF, Graph +from rdflib.compare import IsomorphicGraph, graph_diff, to_isomorphic from linkml_runtime import LINKML @@ -27,7 +27,7 @@ def to_graph(inp: Union[Graph, str], fmt: Optional[str] = "turtle") -> Graph: # If there is no input then return an empty graph if not inp.strip(): return g - if not inp.strip().startswith('{') and '\n' not in inp and '\r' not in inp: + if not inp.strip().startswith("{") and "\n" not in inp and "\r" not in inp: with open(inp) as f: inp = f.read() g.parse(data=inp, format=fmt) @@ -39,7 +39,7 @@ def print_triples(g: Graph) -> None: Print the contents of g into stdout :param g: graph to print """ - g_text = re.sub(r'@prefix.*\n', '', g.serialize(format="turtle")) + g_text = re.sub(r"@prefix.*\n", "", g.serialize(format="turtle")) print(g_text) @@ -51,13 +51,20 @@ def compare_rdf(expected: Union[Graph, str], actual: Union[Graph, str], fmt: Opt :param fmt: RDF format :return: None if they match else summary of difference """ + def rem_metadata(g: Graph) -> IsomorphicGraph: # Remove list declarations from target for s in g.subjects(RDF.type, RDF.List): g.remove((s, RDF.type, RDF.List)) for t in g: - if t[1] in (LINKML.generation_date, LINKML.source_file_date, LINKML.source_file_size, - TYPE.generation_date, TYPE.source_file_date, TYPE.source_file_size): + if t[1] in ( + LINKML.generation_date, + LINKML.source_file_date, + LINKML.source_file_size, + TYPE.generation_date, + TYPE.source_file_date, + TYPE.source_file_size, + ): g.remove(t) g_iso = to_isomorphic(g) return g_iso diff --git a/tests/support/dirutils.py b/tests/support/dirutils.py index 7b68f256..523cc1ee 100644 --- a/tests/support/dirutils.py +++ b/tests/support/dirutils.py @@ -8,7 +8,7 @@ def make_and_clear_directory(dirbase: str) -> None: - """ Make dirbase if necessary and then clear generated files """ + """Make dirbase if necessary and then clear generated files""" import shutil safety_file = os.path.join(dirbase, "generated") @@ -27,7 +27,7 @@ def file_text(txt_or_fname: str) -> str: :param txt_or_fname: :return: """ - if len(txt_or_fname) > 4 and '\n' not in txt_or_fname: + if len(txt_or_fname) > 4 and "\n" not in txt_or_fname: with open(txt_or_fname) as ef: return ef.read() return txt_or_fname @@ -38,27 +38,27 @@ class dircmp(filecmp.dircmp): Compare the content of dir1 and dir2. In contrast with filecmp.dircmp, this subclass compares the content of files with the same path. """ + def phase3(self): """ Find out differences between common files. Ensure we are using content comparison with shallow=False. """ - fcomp = filecmp.cmpfiles(self.left, self.right, self.common_files, - shallow=False) + fcomp = filecmp.cmpfiles(self.left, self.right, self.common_files, shallow=False) self.same_files, self.diff_files, self.funny_files = fcomp - filecmp.dircmp.methodmap['same_files'] = phase3 - filecmp.dircmp.methodmap['diff_files'] = phase3 - filecmp.dircmp.methodmap['funny_files'] = phase3 + filecmp.dircmp.methodmap["same_files"] = phase3 + filecmp.dircmp.methodmap["diff_files"] = phase3 + filecmp.dircmp.methodmap["funny_files"] = phase3 def _do_cmp(f1, f2): bufsize = filecmp.BUFSIZE - with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: + with open(f1, "rb") as fp1, open(f2, "rb") as fp2: while True: b1 = fp1.read(bufsize) b2 = fp2.read(bufsize) - if f1.endswith('.context.jsonld'): + if f1.endswith(".context.jsonld"): b1 = ldcontext_metadata_filter(b1) b2 = ldcontext_metadata_filter(b2) if b1 != b2: @@ -79,14 +79,15 @@ def are_dir_trees_equal(dir1: str, dir2: str) -> Optional[str]: @param dir2: Second directory path @return: None if directories match, else summary of differences - """ + """ + def has_local_diffs(dc: dircmp) -> bool: return bool(dc.diff_files or dc.funny_files or dc.left_only or dc.right_only) def has_diffs(dc: dircmp) -> bool: return has_local_diffs(dc) or any(has_diffs(sd) for sd in dc.subdirs.values()) - dirs_cmp = dircmp(dir1, dir2, ignore=['generated']) + dirs_cmp = dircmp(dir1, dir2, ignore=["generated"]) if has_diffs(dirs_cmp): output = StringIO() with redirect_stdout(output): diff --git a/tests/support/filters.py b/tests/support/filters.py index fa7967db..65e88a37 100644 --- a/tests/support/filters.py +++ b/tests/support/filters.py @@ -1,62 +1,83 @@ +"""Metadata filters for test cases -- various tools to remove metadata from output""" -""" Metadata filters for test cases -- various tools to remove metadata from output """ import re from json import loads from jsonasobj2 import as_json + def ldcontext_metadata_filter(s: str) -> str: """ Metafilter for jsonld context :param s: jsonld context string :return: string stripped of metadata """ - return re.sub(r'Auto generated from .*? by', 'Auto generated from ... by', - re.sub(r'Generation date: .*?\\n', r'Generation date: \\n', s)) + return re.sub( + r"Auto generated from .*? by", + "Auto generated from ... by", + re.sub(r"Generation date: .*?\\n", r"Generation date: \\n", s), + ) def json_metadata_filter(s: str) -> str: - return re.sub(r'("source_file_date": )".*"', r'\1"Friday Sep 27 12:00:00 2003"', - re.sub(r'("generation_date": )".*"', r'\1"Friday Sep 27 12:00:00 2003"', - re.sub(r'("source_file_size": )".*"', r'\1 23600', s))) + return re.sub( + r'("source_file_date": )".*"', + r'\1"Friday Sep 27 12:00:00 2003"', + re.sub( + r'("generation_date": )".*"', + r'\1"Friday Sep 27 12:00:00 2003"', + re.sub(r'("source_file_size": )".*"', r"\1 23600", s), + ), + ) def json_metadata_context_filter(s: str) -> str: - return re.sub(r'file:///.*/', r'', json_metadata_filter(s)) + return re.sub(r"file:///.*/", r"", json_metadata_filter(s)) def metadata_filter(s: str) -> str: - return re.sub(r'(# Auto generated from ).*(\.yaml by pythongen\.py version:) .*', r'\1\2', - re.sub(r'(# Generation date:) .*', r'\1', re.sub(r'\r\n', '\n', s))) + return re.sub( + r"(# Auto generated from ).*(\.yaml by pythongen\.py version:) .*", + r"\1\2", + re.sub(r"(# Generation date:) .*", r"\1", re.sub(r"\r\n", "\n", s)), + ) def yaml_filter(s: str) -> str: # source_file_date: Thu Jul 9 14:37:10 2020 # source_file_size: 671 # generation_date: 2020-07-09 15:43 - return re.sub(r'(source_file_date: ).*', r'\1Friday Sep 27 12:00:00 2003', - re.sub(r'(generation_date: ).*', r'\1Friday Sep 27 12:00:00 2003', - re.sub(r'(source_file_size: ).*', r'\1 23600', s))) + return re.sub( + r"(source_file_date: ).*", + r"\1Friday Sep 27 12:00:00 2003", + re.sub( + r"(generation_date: ).*", + r"\1Friday Sep 27 12:00:00 2003", + re.sub(r"(source_file_size: ).*", r"\1 23600", s), + ), + ) def nb_filter(s: str) -> str: - """ Filter for jupyter (ipynb) notebooks """ + """Filter for jupyter (ipynb) notebooks""" # It is easier to deal with notebook content in JSON s_json = loads(ldcontext_metadata_filter(s)) for cell in s_json.cells: - if hasattr(cell, 'execution_count'): + if hasattr(cell, "execution_count"): cell.execution_count = 1 - if hasattr(cell, 'metadata'): - delattr(cell, 'metadata') - if hasattr(cell, 'outputs'): + if hasattr(cell, "metadata"): + delattr(cell, "metadata") + if hasattr(cell, "outputs"): del_outputs = [] for output in cell.outputs: to_del = [] - if hasattr(output, 'text'): + if hasattr(output, "text"): for line in output.text: - if 'WARNING: You are using pip' in line or\ - 'You should consider upgrading via' in line or\ - 'Requirement already satisfied:' in line: + if ( + "WARNING: You are using pip" in line + or "You should consider upgrading via" in line + or "Requirement already satisfied:" in line + ): to_del.append(line) for del_line in to_del: output.text.remove(del_line) @@ -65,8 +86,8 @@ def nb_filter(s: str) -> str: if del_outputs: for del_output in del_outputs: cell.outputs.remove(del_output) - if hasattr(s_json.metadata, 'language_info'): - if hasattr(s_json.metadata.language_info, 'version'): - s_json.metadata.language_info.version = '3' + if hasattr(s_json.metadata, "language_info"): + if hasattr(s_json.metadata.language_info, "version"): + s_json.metadata.language_info.version = "3" return as_json(s_json) diff --git a/tests/support/mismatchlog.py b/tests/support/mismatchlog.py index c51fb47d..baa92342 100644 --- a/tests/support/mismatchlog.py +++ b/tests/support/mismatchlog.py @@ -2,7 +2,7 @@ import sys from typing import Optional -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) class MismatchLog: @@ -13,6 +13,7 @@ class MismatchLog: line_no - the line number in the python file difference_text - the details on the difference. Used for RDF and other non-ascii files """ + class MismatchLogEntry: class StackFrame: def __init__(self, filename: str, method: str, line: int) -> None: @@ -29,18 +30,21 @@ def __init__(self, file_or_directory: str, msg: Optional[str]) -> None: self.call_stack = list() frame = sys._getframe(2) while True: - self.call_stack.append(MismatchLog.MismatchLogEntry.StackFrame(frame.f_code.co_filename, - frame.f_code.co_name, frame.f_lineno)) + self.call_stack.append( + MismatchLog.MismatchLogEntry.StackFrame( + frame.f_code.co_filename, frame.f_code.co_name, frame.f_lineno + ) + ) if frame.f_code.co_name.startswith("test_"): break frame = frame.f_back def __str__(self): rval = [f'Validation error: File "{os.path.relpath(self.file_or_directory, base_dir)}", line 1'] - rval.append("Stack: " + '\n\t\t'.join([str(e) for e in self.call_stack])) + rval.append("Stack: " + "\n\t\t".join([str(e) for e in self.call_stack])) if self.msg: rval.append(self.msg.rstrip().capitalize()) - return '\n'.join(rval) + '\n' + return "\n".join(rval) + "\n" def __init__(self) -> None: self.entries: list[MismatchLog.MismatchLogEntry] = list() diff --git a/tests/support/test_environment.py b/tests/support/test_environment.py index 35efa086..c1eb62bb 100644 --- a/tests/support/test_environment.py +++ b/tests/support/test_environment.py @@ -9,7 +9,7 @@ from importlib import import_module from io import StringIO from pathlib import Path -from typing import Optional, Callable, Union +from typing import Callable, Optional, Union from tests.support.dirutils import are_dir_trees_equal from tests.support.mismatchlog import MismatchLog @@ -17,11 +17,13 @@ def no_click_exit(_self, code=0): from tests import CLIExitException + raise CLIExitException(code) # This import has to occur here -import click +import click # noqa: E402 + click.core.Context.exit = no_click_exit @@ -29,7 +31,7 @@ class MismatchAction(Enum): Ignore = 0 Report = 1 Fail = 2 - FailOnce = 3 # Run all tests and then fail if there are any mismatches + FailOnce = 3 # Run all tests and then fail if there are any mismatches class TestEnvironment: @@ -38,16 +40,17 @@ class TestEnvironment: __test__ = False """ Testing environment """ + def __init__(self, filedir: str) -> None: - self.cwd = os.path.dirname(filedir) # base directory for indir, outdir and tempdir - self.indir = os.path.join(self.cwd, 'input') # Input files - self.outdir = os.path.join(self.cwd, 'output') # Expected/actual output files - self.tempdir = os.path.join(self.cwd, 'temp') # Scratch directory for temporary work + self.cwd = os.path.dirname(filedir) # base directory for indir, outdir and tempdir + self.indir = os.path.join(self.cwd, "input") # Input files + self.outdir = os.path.join(self.cwd, "output") # Expected/actual output files + self.tempdir = os.path.join(self.cwd, "temp") # Scratch directory for temporary work # Get the parent's directory name. If it is a test directory, borrow from its environment parent = Path(self.cwd).parts[-2] - if parent.startswith('test'): - parent_env = import_module('..environment', __package__) + if parent.startswith("test"): + parent_env = import_module("..environment", __package__) self.import_map = parent_env.env.import_map self.mismatch_action = parent_env.env.mismatch_action self.root_input_path = parent_env.env.root_input_path @@ -56,8 +59,10 @@ def __init__(self, filedir: str) -> None: self._log = parent_env.env._log else: from tests import USE_LOCAL_IMPORT_MAP - self.import_map = self.input_path('local_import_map.json') if USE_LOCAL_IMPORT_MAP else None + + self.import_map = self.input_path("local_import_map.json") if USE_LOCAL_IMPORT_MAP else None from tests import DEFAULT_MISMATCH_ACTION + self.mismatch_action = DEFAULT_MISMATCH_ACTION self.root_input_path = self.input_path self.root_expected_path = self.expected_path @@ -69,35 +74,35 @@ def _check_changed(test_file: str, runtime_file: str) -> None: if not filecmp.cmp(test_file, runtime_file): print( f"WARNING: Test file {test_file} does not match {runtime_file}. " - f"You may want to update the test version and rerun") + f"You may want to update the test version and rerun" + ) from tests import USE_LOCAL_IMPORT_MAP + if USE_LOCAL_IMPORT_MAP and not TestEnvironment.import_map_warning_emitted: - print( - f"WARNING: USE_LOCAL_IMPORT_MAP must be reset to False before completing submission." - ) + print("WARNING: USE_LOCAL_IMPORT_MAP must be reset to False before completing submission.") TestEnvironment.import_map_warning_emitted = True def clear_log(self) -> None: - """ Clear the output log """ + """Clear the output log""" self._log = MismatchLog() def input_path(self, *path: str) -> str: - """ Create a file path in the local input directory """ + """Create a file path in the local input directory""" return os.path.join(self.indir, *[p for p in path if p]) def expected_path(self, *path: str) -> str: - """ Create a file path in the local output directory """ + """Create a file path in the local output directory""" return os.path.join(self.outdir, *[p for p in path if p]) def actual_path(self, *path: str, is_dir: bool = False) -> str: - """ Return the full path to the path fragments in path """ + """Return the full path to the path fragments in path""" dir_path = [p for p in (path if is_dir else path[:-1]) if p] self.make_temp_dir(*dir_path, clear=False) return os.path.join(self.tempdir, *[p for p in path if p]) def temp_file_path(self, *path: str, is_dir: bool = False) -> str: - """ Create the directories down to the path fragments in path. If is_dir is True, create and clear the - innermost directory + """Create the directories down to the path fragments in path. If is_dir is True, create and clear the + innermost directory """ return self.actual_path(*path, is_dir=is_dir) @@ -106,7 +111,7 @@ def log(self, file_or_directory: str, message: Optional[str] = None) -> None: @property def verb(self) -> str: - return 'will be' if self.fail_on_error else 'was' + return "will be" if self.fail_on_error else "was" @property def fail_on_error(self) -> bool: @@ -117,11 +122,11 @@ def report_errors(self) -> bool: return self.mismatch_action != MismatchAction.Ignore def __str__(self): - """ Return the current state of the log file """ - return '\n\n'.join([str(e) for e in self._log.entries]) + """Return the current state of the log file""" + return "\n\n".join([str(e) for e in self._log.entries]) def make_temp_dir(self, *paths: str, clear: bool = True) -> str: - """ Create and initialize a list of paths """ + """Create and initialize a list of paths""" full_path = self.tempdir TestEnvironment.make_testing_directory(full_path) if len(paths): @@ -137,7 +142,7 @@ def string_comparator(self, expected: str, actual: str) -> Optional[str]: :param actual: actual string :return: Error message if mismatch else None """ - if expected.replace('\r\n', '\n').strip() != actual.replace('\r\n', '\n').strip(): + if expected.replace("\r\n", "\n").strip() != actual.replace("\r\n", "\n").strip(): return f"Output {self.verb} changed." @staticmethod @@ -184,9 +189,15 @@ def generate_directory(self, dirname: Union[str, list[str]], generator: Callable else: shutil.rmtree(temp_output_directory) - def generate_single_file(self, filename: Union[str, list[str]], generator: Callable[[Optional[str]], Optional[str]], - value_is_returned: bool = False, filtr: Callable[[str], str] = None, - comparator: Callable[[str, str], str] = None, use_testing_root: bool = False) -> str: + def generate_single_file( + self, + filename: Union[str, list[str]], + generator: Callable[[Optional[str]], Optional[str]], + value_is_returned: bool = False, + filtr: Callable[[str], str] = None, + comparator: Callable[[str, str], str] = None, + use_testing_root: bool = False, + ) -> str: """ Invoke the generator and compare the actual results to the expected. :param filename: relative file name(s) (no path) @@ -198,8 +209,11 @@ def generate_single_file(self, filename: Union[str, list[str]], generator: Calla :return: the generator output """ # If no filter, default to identity function - if not filtr: - filtr = lambda s: s + if filtr is None: + + def filtr(s): + return s + filename = filename if isinstance(filename, list) else [filename] actual_file = self.root_temp_file_path(*filename) if use_testing_root else self.actual_path(*filename) expected_file = self.root_expected_path(*filename) if use_testing_root else self.expected_path(*filename) @@ -209,6 +223,7 @@ def generate_single_file(self, filename: Union[str, list[str]], generator: Calla else: outf = StringIO() from tests import CLIExitException + with contextlib.redirect_stdout(outf): try: generator() @@ -219,14 +234,19 @@ def generate_single_file(self, filename: Union[str, list[str]], generator: Calla if not self.eval_single_file(expected_file, actual, filtr, comparator): if self.fail_on_error: self.make_temp_dir(os.path.dirname(actual_file), clear=False) - with open(actual_file, 'w', encoding='UTF-8') as actualf: + with open(actual_file, "w", encoding="UTF-8") as actualf: actualf.write(actual) return actual - def eval_single_file(self, expected_file_path: str, actual_text: str, filtr: Callable[[str], str] = lambda s: s, - comparator: Callable[[str, str], str] = None) -> bool: - """ Compare actual_text to the contents of the expected file. Log a message if there is a mismatch and - overwrite the expected file if we're not in the fail on error mode + def eval_single_file( + self, + expected_file_path: str, + actual_text: str, + filtr: Callable[[str], str] = lambda s: s, + comparator: Callable[[str, str], str] = None, + ) -> bool: + """Compare actual_text to the contents of the expected file. Log a message if there is a mismatch and + overwrite the expected file if we're not in the fail on error mode """ if comparator is None: comparator = self.string_comparator @@ -238,12 +258,12 @@ def eval_single_file(self, expected_file_path: str, actual_text: str, filtr: Cal msg = f"New file {self.verb} created" cmsg = comparator(actual_text, actual_text) if cmsg: - msg = msg + '\n' + cmsg + msg = msg + "\n" + cmsg if msg: self.log(expected_file_path, msg) if msg and not self.fail_on_error: self.make_temp_dir(os.path.dirname(expected_file_path), clear=False) - with open(expected_file_path, 'w', encoding='UTF-8') as outf: + with open(expected_file_path, "w", encoding="UTF-8") as outf: outf.write(actual_text) return not msg @@ -258,6 +278,7 @@ class InheritedTestCase(TestEnvironmentTestCase): env = TestEnvironment(__file__) ... """ + env: TestEnvironment = None @classmethod diff --git a/tests/test_enumerations/environment.py b/tests/test_enumerations/environment.py index 8b9a1a7f..bdc14a95 100644 --- a/tests/test_enumerations/environment.py +++ b/tests/test_enumerations/environment.py @@ -1,4 +1,3 @@ from tests.support.test_environment import TestEnvironment env = TestEnvironment(__file__) - diff --git a/tests/test_index/__init__.py b/tests/test_index/__init__.py index 53405302..ff131072 100644 --- a/tests/test_index/__init__.py +++ b/tests/test_index/__init__.py @@ -2,5 +2,5 @@ TESTING_DIR = os.path.abspath(os.path.dirname(__file__)) -INPUT_DIR = os.path.join(TESTING_DIR, 'input') -OUTPUT_DIR = os.path.join(TESTING_DIR, 'output') +INPUT_DIR = os.path.join(TESTING_DIR, "input") +OUTPUT_DIR = os.path.join(TESTING_DIR, "output") diff --git a/tests/test_index/model/container_test.py b/tests/test_index/model/container_test.py index 84c2603c..443c13a8 100644 --- a/tests/test_index/model/container_test.py +++ b/tests/test_index/model/container_test.py @@ -6,44 +6,44 @@ # description: Information about people, based on [schema.org](http://schema.org) # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses import re -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str -from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from jsonasobj2 import as_dict from rdflib import URIRef + +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import Bool, XSDDate +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import Bool, XSDDate, empty_dict, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" version = None # Namespaces -CODE = CurieNamespace('CODE', 'http://example.org/code/') -GEO = CurieNamespace('GEO', 'http://example.org/geoloc/') -GSSO = CurieNamespace('GSSO', 'http://purl.obolibrary.org/obo/GSSO_') -P = CurieNamespace('P', 'http://example.org/P/') -ROR = CurieNamespace('ROR', 'http://example.org/ror/') -FAMREL = CurieNamespace('famrel', 'https://example.org/FamilialRelations#') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -PERSONINFO = CurieNamespace('personinfo', 'https://w3id.org/linkml/examples/personinfo/') -PROV = CurieNamespace('prov', 'http://www.w3.org/ns/prov#') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SKOS = CurieNamespace('skos', 'http://example.org/UNKNOWN/skos/') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +CODE = CurieNamespace("CODE", "http://example.org/code/") +GEO = CurieNamespace("GEO", "http://example.org/geoloc/") +GSSO = CurieNamespace("GSSO", "http://purl.obolibrary.org/obo/GSSO_") +P = CurieNamespace("P", "http://example.org/P/") +ROR = CurieNamespace("ROR", "http://example.org/ror/") +FAMREL = CurieNamespace("famrel", "https://example.org/FamilialRelations#") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +PERSONINFO = CurieNamespace("personinfo", "https://w3id.org/linkml/examples/personinfo/") +PROV = CurieNamespace("prov", "http://www.w3.org/ns/prov#") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SKOS = CurieNamespace("skos", "http://example.org/UNKNOWN/skos/") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = PERSONINFO # Types + # Class references class NamedThingId(extended_str): pass @@ -78,6 +78,7 @@ class NamedThing(YAMLRoot): """ A generic grouping for any identifiable entity """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PERSONINFO.NamedThing @@ -113,6 +114,7 @@ class Person(NamedThing): """ A person (alive, dead, undead, or fictional). """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SCHEMA.Person @@ -126,8 +128,12 @@ class Person(NamedThing): age_in_years: Optional[int] = None gender: Optional[Union[str, "GenderType"]] = None current_address: Optional[Union[dict, "Address"]] = None - has_employment_history: Optional[Union[Union[dict, "EmploymentEvent"], list[Union[dict, "EmploymentEvent"]]]] = empty_list() - has_familial_relationships: Optional[Union[Union[dict, "FamilialRelationship"], list[Union[dict, "FamilialRelationship"]]]] = empty_list() + has_employment_history: Optional[Union[Union[dict, "EmploymentEvent"], list[Union[dict, "EmploymentEvent"]]]] = ( + empty_list() + ) + has_familial_relationships: Optional[ + Union[Union[dict, "FamilialRelationship"], list[Union[dict, "FamilialRelationship"]]] + ] = empty_list() has_medical_history: Optional[Union[Union[dict, "MedicalEvent"], list[Union[dict, "MedicalEvent"]]]] = empty_list() aliases: Optional[Union[str, list[str]]] = empty_list() @@ -153,16 +159,27 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.current_address = Address(**as_dict(self.current_address)) if not isinstance(self.has_employment_history, list): - self.has_employment_history = [self.has_employment_history] if self.has_employment_history is not None else [] - self.has_employment_history = [v if isinstance(v, EmploymentEvent) else EmploymentEvent(**as_dict(v)) for v in self.has_employment_history] + self.has_employment_history = ( + [self.has_employment_history] if self.has_employment_history is not None else [] + ) + self.has_employment_history = [ + v if isinstance(v, EmploymentEvent) else EmploymentEvent(**as_dict(v)) for v in self.has_employment_history + ] if not isinstance(self.has_familial_relationships, list): - self.has_familial_relationships = [self.has_familial_relationships] if self.has_familial_relationships is not None else [] - self.has_familial_relationships = [v if isinstance(v, FamilialRelationship) else FamilialRelationship(**as_dict(v)) for v in self.has_familial_relationships] + self.has_familial_relationships = ( + [self.has_familial_relationships] if self.has_familial_relationships is not None else [] + ) + self.has_familial_relationships = [ + v if isinstance(v, FamilialRelationship) else FamilialRelationship(**as_dict(v)) + for v in self.has_familial_relationships + ] if not isinstance(self.has_medical_history, list): self.has_medical_history = [self.has_medical_history] if self.has_medical_history is not None else [] - self.has_medical_history = [v if isinstance(v, MedicalEvent) else MedicalEvent(**as_dict(v)) for v in self.has_medical_history] + self.has_medical_history = [ + v if isinstance(v, MedicalEvent) else MedicalEvent(**as_dict(v)) for v in self.has_medical_history + ] if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] @@ -176,6 +193,7 @@ class HasAliases(YAMLRoot): """ A mixin applied to any class that can have aliases/alternateNames """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PERSONINFO.HasAliases @@ -198,6 +216,7 @@ class Organization(NamedThing): """ An organization such as a company or university """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SCHEMA.Organization @@ -510,7 +529,9 @@ class Container(YAMLRoot): class_model_uri: ClassVar[URIRef] = PERSONINFO.Container persons: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = empty_dict() - organizations: Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]] = empty_dict() + organizations: Optional[ + Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self._normalize_inlined_as_list(slot_name="persons", slot_type=Person, key_name="id", keyed=True) @@ -527,21 +548,19 @@ class RelationshipType(EnumDefinitionImpl): name="RelationshipType", ) + class FamilialRelationshipType(EnumDefinitionImpl): - SIBLING_OF = PermissibleValue(text="SIBLING_OF", - meaning=FAMREL["01"]) - PARENT_OF = PermissibleValue(text="PARENT_OF", - meaning=FAMREL["02"]) - CHILD_OF = PermissibleValue(text="CHILD_OF", - meaning=FAMREL["01"]) - FATHER_OF = PermissibleValue(text="FATHER_OF", - meaning=FAMREL["11"]) + SIBLING_OF = PermissibleValue(text="SIBLING_OF", meaning=FAMREL["01"]) + PARENT_OF = PermissibleValue(text="PARENT_OF", meaning=FAMREL["02"]) + CHILD_OF = PermissibleValue(text="CHILD_OF", meaning=FAMREL["01"]) + FATHER_OF = PermissibleValue(text="FATHER_OF", meaning=FAMREL["11"]) _defn = EnumDefinition( name="FamilialRelationshipType", ) + class GenderType(EnumDefinitionImpl): _defn = EnumDefinition( @@ -550,24 +569,13 @@ class GenderType(EnumDefinitionImpl): @classmethod def _addvals(cls): - setattr(cls, "nonbinary man", - PermissibleValue(text="nonbinary man", - meaning=GSSO["009254"]) ) - setattr(cls, "nonbinary woman", - PermissibleValue(text="nonbinary woman", - meaning=GSSO["009253"]) ) - setattr(cls, "transgender woman", - PermissibleValue(text="transgender woman", - meaning=GSSO["000384"]) ) - setattr(cls, "transgender man", - PermissibleValue(text="transgender man", - meaning=GSSO["000372"]) ) - setattr(cls, "cisgender man", - PermissibleValue(text="cisgender man", - meaning=GSSO["000371"]) ) - setattr(cls, "cisgender woman", - PermissibleValue(text="cisgender woman", - meaning=GSSO["000385"]) ) + setattr(cls, "nonbinary man", PermissibleValue(text="nonbinary man", meaning=GSSO["009254"])) + setattr(cls, "nonbinary woman", PermissibleValue(text="nonbinary woman", meaning=GSSO["009253"])) + setattr(cls, "transgender woman", PermissibleValue(text="transgender woman", meaning=GSSO["000384"])) + setattr(cls, "transgender man", PermissibleValue(text="transgender man", meaning=GSSO["000372"])) + setattr(cls, "cisgender man", PermissibleValue(text="cisgender man", meaning=GSSO["000371"])) + setattr(cls, "cisgender woman", PermissibleValue(text="cisgender woman", meaning=GSSO["000385"])) + class DiagnosisType(EnumDefinitionImpl): @@ -575,109 +583,315 @@ class DiagnosisType(EnumDefinitionImpl): name="DiagnosisType", ) + # Slots class slots: pass -slots.id = Slot(uri=SCHEMA.identifier, name="id", curie=SCHEMA.curie('identifier'), - model_uri=PERSONINFO.id, domain=None, range=URIRef) - -slots.name = Slot(uri=SCHEMA.name, name="name", curie=SCHEMA.curie('name'), - model_uri=PERSONINFO.name, domain=None, range=Optional[str]) - -slots.description = Slot(uri=SCHEMA.description, name="description", curie=SCHEMA.curie('description'), - model_uri=PERSONINFO.description, domain=None, range=Optional[str]) - -slots.image = Slot(uri=SCHEMA.image, name="image", curie=SCHEMA.curie('image'), - model_uri=PERSONINFO.image, domain=None, range=Optional[str]) - -slots.gender = Slot(uri=SCHEMA.gender, name="gender", curie=SCHEMA.curie('gender'), - model_uri=PERSONINFO.gender, domain=None, range=Optional[Union[str, "GenderType"]]) - -slots.primary_email = Slot(uri=SCHEMA.email, name="primary_email", curie=SCHEMA.curie('email'), - model_uri=PERSONINFO.primary_email, domain=None, range=Optional[str]) - -slots.birth_date = Slot(uri=SCHEMA.birthDate, name="birth_date", curie=SCHEMA.curie('birthDate'), - model_uri=PERSONINFO.birth_date, domain=None, range=Optional[str]) - -slots.employed_at = Slot(uri=PERSONINFO.employed_at, name="employed_at", curie=PERSONINFO.curie('employed_at'), - model_uri=PERSONINFO.employed_at, domain=None, range=Optional[Union[str, OrganizationId]]) - -slots.is_current = Slot(uri=PERSONINFO.is_current, name="is_current", curie=PERSONINFO.curie('is_current'), - model_uri=PERSONINFO.is_current, domain=None, range=Optional[Union[bool, Bool]]) - -slots.has_employment_history = Slot(uri=PERSONINFO.has_employment_history, name="has_employment_history", curie=PERSONINFO.curie('has_employment_history'), - model_uri=PERSONINFO.has_employment_history, domain=None, range=Optional[Union[Union[dict, EmploymentEvent], list[Union[dict, EmploymentEvent]]]]) - -slots.has_medical_history = Slot(uri=PERSONINFO.has_medical_history, name="has_medical_history", curie=PERSONINFO.curie('has_medical_history'), - model_uri=PERSONINFO.has_medical_history, domain=None, range=Optional[Union[Union[dict, MedicalEvent], list[Union[dict, MedicalEvent]]]]) - -slots.has_familial_relationships = Slot(uri=PERSONINFO.has_familial_relationships, name="has_familial_relationships", curie=PERSONINFO.curie('has_familial_relationships'), - model_uri=PERSONINFO.has_familial_relationships, domain=None, range=Optional[Union[Union[dict, FamilialRelationship], list[Union[dict, FamilialRelationship]]]]) - -slots.in_location = Slot(uri=PERSONINFO.in_location, name="in_location", curie=PERSONINFO.curie('in_location'), - model_uri=PERSONINFO.in_location, domain=None, range=Optional[Union[str, PlaceId]]) - -slots.current_address = Slot(uri=PERSONINFO.current_address, name="current_address", curie=PERSONINFO.curie('current_address'), - model_uri=PERSONINFO.current_address, domain=None, range=Optional[Union[dict, Address]]) - -slots.age_in_years = Slot(uri=PERSONINFO.age_in_years, name="age_in_years", curie=PERSONINFO.curie('age_in_years'), - model_uri=PERSONINFO.age_in_years, domain=None, range=Optional[int]) - -slots.related_to = Slot(uri=PERSONINFO.related_to, name="related_to", curie=PERSONINFO.curie('related_to'), - model_uri=PERSONINFO.related_to, domain=None, range=Optional[str]) - -slots.type = Slot(uri=PERSONINFO.type, name="type", curie=PERSONINFO.curie('type'), - model_uri=PERSONINFO.type, domain=None, range=Optional[Union[str, "RelationshipType"]]) - -slots.street = Slot(uri=PERSONINFO.street, name="street", curie=PERSONINFO.curie('street'), - model_uri=PERSONINFO.street, domain=None, range=Optional[str]) - -slots.city = Slot(uri=PERSONINFO.city, name="city", curie=PERSONINFO.curie('city'), - model_uri=PERSONINFO.city, domain=None, range=Optional[str]) - -slots.mission_statement = Slot(uri=PERSONINFO.mission_statement, name="mission_statement", curie=PERSONINFO.curie('mission_statement'), - model_uri=PERSONINFO.mission_statement, domain=None, range=Optional[str]) - -slots.founding_date = Slot(uri=PERSONINFO.founding_date, name="founding_date", curie=PERSONINFO.curie('founding_date'), - model_uri=PERSONINFO.founding_date, domain=None, range=Optional[str]) - -slots.founding_location = Slot(uri=PERSONINFO.founding_location, name="founding_location", curie=PERSONINFO.curie('founding_location'), - model_uri=PERSONINFO.founding_location, domain=None, range=Optional[Union[str, PlaceId]]) - -slots.postal_code = Slot(uri=PERSONINFO.postal_code, name="postal_code", curie=PERSONINFO.curie('postal_code'), - model_uri=PERSONINFO.postal_code, domain=None, range=Optional[str]) - -slots.started_at_time = Slot(uri=PROV.startedAtTime, name="started_at_time", curie=PROV.curie('startedAtTime'), - model_uri=PERSONINFO.started_at_time, domain=None, range=Optional[Union[str, XSDDate]]) - -slots.duration = Slot(uri=PERSONINFO.duration, name="duration", curie=PERSONINFO.curie('duration'), - model_uri=PERSONINFO.duration, domain=None, range=Optional[float]) - -slots.diagnosis = Slot(uri=PERSONINFO.diagnosis, name="diagnosis", curie=PERSONINFO.curie('diagnosis'), - model_uri=PERSONINFO.diagnosis, domain=None, range=Optional[Union[dict, DiagnosisConcept]]) - -slots.procedure = Slot(uri=PERSONINFO.procedure, name="procedure", curie=PERSONINFO.curie('procedure'), - model_uri=PERSONINFO.procedure, domain=None, range=Optional[Union[dict, ProcedureConcept]]) - -slots.ended_at_time = Slot(uri=PROV.endedAtTime, name="ended_at_time", curie=PROV.curie('endedAtTime'), - model_uri=PERSONINFO.ended_at_time, domain=None, range=Optional[Union[str, XSDDate]]) - -slots.persons = Slot(uri=PERSONINFO.persons, name="persons", curie=PERSONINFO.curie('persons'), - model_uri=PERSONINFO.persons, domain=None, range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]]) - -slots.organizations = Slot(uri=PERSONINFO.organizations, name="organizations", curie=PERSONINFO.curie('organizations'), - model_uri=PERSONINFO.organizations, domain=None, range=Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]]) - -slots.hasAliases__aliases = Slot(uri=PERSONINFO.aliases, name="hasAliases__aliases", curie=PERSONINFO.curie('aliases'), - model_uri=PERSONINFO.hasAliases__aliases, domain=None, range=Optional[Union[str, list[str]]]) - -slots.Person_primary_email = Slot(uri=SCHEMA.email, name="Person_primary_email", curie=SCHEMA.curie('email'), - model_uri=PERSONINFO.Person_primary_email, domain=Person, range=Optional[str], - pattern=re.compile(r'^\S+@[\S+\.]+\S+')) - -slots.FamilialRelationship_type = Slot(uri=PERSONINFO.type, name="FamilialRelationship_type", curie=PERSONINFO.curie('type'), - model_uri=PERSONINFO.FamilialRelationship_type, domain=FamilialRelationship, range=Union[str, "FamilialRelationshipType"]) -slots.FamilialRelationship_related_to = Slot(uri=PERSONINFO.related_to, name="FamilialRelationship_related_to", curie=PERSONINFO.curie('related_to'), - model_uri=PERSONINFO.FamilialRelationship_related_to, domain=FamilialRelationship, range=Union[str, PersonId]) +slots.id = Slot( + uri=SCHEMA.identifier, + name="id", + curie=SCHEMA.curie("identifier"), + model_uri=PERSONINFO.id, + domain=None, + range=URIRef, +) + +slots.name = Slot( + uri=SCHEMA.name, + name="name", + curie=SCHEMA.curie("name"), + model_uri=PERSONINFO.name, + domain=None, + range=Optional[str], +) + +slots.description = Slot( + uri=SCHEMA.description, + name="description", + curie=SCHEMA.curie("description"), + model_uri=PERSONINFO.description, + domain=None, + range=Optional[str], +) + +slots.image = Slot( + uri=SCHEMA.image, + name="image", + curie=SCHEMA.curie("image"), + model_uri=PERSONINFO.image, + domain=None, + range=Optional[str], +) + +slots.gender = Slot( + uri=SCHEMA.gender, + name="gender", + curie=SCHEMA.curie("gender"), + model_uri=PERSONINFO.gender, + domain=None, + range=Optional[Union[str, "GenderType"]], +) + +slots.primary_email = Slot( + uri=SCHEMA.email, + name="primary_email", + curie=SCHEMA.curie("email"), + model_uri=PERSONINFO.primary_email, + domain=None, + range=Optional[str], +) + +slots.birth_date = Slot( + uri=SCHEMA.birthDate, + name="birth_date", + curie=SCHEMA.curie("birthDate"), + model_uri=PERSONINFO.birth_date, + domain=None, + range=Optional[str], +) + +slots.employed_at = Slot( + uri=PERSONINFO.employed_at, + name="employed_at", + curie=PERSONINFO.curie("employed_at"), + model_uri=PERSONINFO.employed_at, + domain=None, + range=Optional[Union[str, OrganizationId]], +) + +slots.is_current = Slot( + uri=PERSONINFO.is_current, + name="is_current", + curie=PERSONINFO.curie("is_current"), + model_uri=PERSONINFO.is_current, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.has_employment_history = Slot( + uri=PERSONINFO.has_employment_history, + name="has_employment_history", + curie=PERSONINFO.curie("has_employment_history"), + model_uri=PERSONINFO.has_employment_history, + domain=None, + range=Optional[Union[Union[dict, EmploymentEvent], list[Union[dict, EmploymentEvent]]]], +) + +slots.has_medical_history = Slot( + uri=PERSONINFO.has_medical_history, + name="has_medical_history", + curie=PERSONINFO.curie("has_medical_history"), + model_uri=PERSONINFO.has_medical_history, + domain=None, + range=Optional[Union[Union[dict, MedicalEvent], list[Union[dict, MedicalEvent]]]], +) + +slots.has_familial_relationships = Slot( + uri=PERSONINFO.has_familial_relationships, + name="has_familial_relationships", + curie=PERSONINFO.curie("has_familial_relationships"), + model_uri=PERSONINFO.has_familial_relationships, + domain=None, + range=Optional[Union[Union[dict, FamilialRelationship], list[Union[dict, FamilialRelationship]]]], +) + +slots.in_location = Slot( + uri=PERSONINFO.in_location, + name="in_location", + curie=PERSONINFO.curie("in_location"), + model_uri=PERSONINFO.in_location, + domain=None, + range=Optional[Union[str, PlaceId]], +) + +slots.current_address = Slot( + uri=PERSONINFO.current_address, + name="current_address", + curie=PERSONINFO.curie("current_address"), + model_uri=PERSONINFO.current_address, + domain=None, + range=Optional[Union[dict, Address]], +) + +slots.age_in_years = Slot( + uri=PERSONINFO.age_in_years, + name="age_in_years", + curie=PERSONINFO.curie("age_in_years"), + model_uri=PERSONINFO.age_in_years, + domain=None, + range=Optional[int], +) + +slots.related_to = Slot( + uri=PERSONINFO.related_to, + name="related_to", + curie=PERSONINFO.curie("related_to"), + model_uri=PERSONINFO.related_to, + domain=None, + range=Optional[str], +) + +slots.type = Slot( + uri=PERSONINFO.type, + name="type", + curie=PERSONINFO.curie("type"), + model_uri=PERSONINFO.type, + domain=None, + range=Optional[Union[str, "RelationshipType"]], +) + +slots.street = Slot( + uri=PERSONINFO.street, + name="street", + curie=PERSONINFO.curie("street"), + model_uri=PERSONINFO.street, + domain=None, + range=Optional[str], +) + +slots.city = Slot( + uri=PERSONINFO.city, + name="city", + curie=PERSONINFO.curie("city"), + model_uri=PERSONINFO.city, + domain=None, + range=Optional[str], +) + +slots.mission_statement = Slot( + uri=PERSONINFO.mission_statement, + name="mission_statement", + curie=PERSONINFO.curie("mission_statement"), + model_uri=PERSONINFO.mission_statement, + domain=None, + range=Optional[str], +) + +slots.founding_date = Slot( + uri=PERSONINFO.founding_date, + name="founding_date", + curie=PERSONINFO.curie("founding_date"), + model_uri=PERSONINFO.founding_date, + domain=None, + range=Optional[str], +) + +slots.founding_location = Slot( + uri=PERSONINFO.founding_location, + name="founding_location", + curie=PERSONINFO.curie("founding_location"), + model_uri=PERSONINFO.founding_location, + domain=None, + range=Optional[Union[str, PlaceId]], +) + +slots.postal_code = Slot( + uri=PERSONINFO.postal_code, + name="postal_code", + curie=PERSONINFO.curie("postal_code"), + model_uri=PERSONINFO.postal_code, + domain=None, + range=Optional[str], +) + +slots.started_at_time = Slot( + uri=PROV.startedAtTime, + name="started_at_time", + curie=PROV.curie("startedAtTime"), + model_uri=PERSONINFO.started_at_time, + domain=None, + range=Optional[Union[str, XSDDate]], +) + +slots.duration = Slot( + uri=PERSONINFO.duration, + name="duration", + curie=PERSONINFO.curie("duration"), + model_uri=PERSONINFO.duration, + domain=None, + range=Optional[float], +) + +slots.diagnosis = Slot( + uri=PERSONINFO.diagnosis, + name="diagnosis", + curie=PERSONINFO.curie("diagnosis"), + model_uri=PERSONINFO.diagnosis, + domain=None, + range=Optional[Union[dict, DiagnosisConcept]], +) + +slots.procedure = Slot( + uri=PERSONINFO.procedure, + name="procedure", + curie=PERSONINFO.curie("procedure"), + model_uri=PERSONINFO.procedure, + domain=None, + range=Optional[Union[dict, ProcedureConcept]], +) + +slots.ended_at_time = Slot( + uri=PROV.endedAtTime, + name="ended_at_time", + curie=PROV.curie("endedAtTime"), + model_uri=PERSONINFO.ended_at_time, + domain=None, + range=Optional[Union[str, XSDDate]], +) + +slots.persons = Slot( + uri=PERSONINFO.persons, + name="persons", + curie=PERSONINFO.curie("persons"), + model_uri=PERSONINFO.persons, + domain=None, + range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]], +) + +slots.organizations = Slot( + uri=PERSONINFO.organizations, + name="organizations", + curie=PERSONINFO.curie("organizations"), + model_uri=PERSONINFO.organizations, + domain=None, + range=Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]], +) + +slots.hasAliases__aliases = Slot( + uri=PERSONINFO.aliases, + name="hasAliases__aliases", + curie=PERSONINFO.curie("aliases"), + model_uri=PERSONINFO.hasAliases__aliases, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.Person_primary_email = Slot( + uri=SCHEMA.email, + name="Person_primary_email", + curie=SCHEMA.curie("email"), + model_uri=PERSONINFO.Person_primary_email, + domain=Person, + range=Optional[str], + pattern=re.compile(r"^\S+@[\S+\.]+\S+"), +) + +slots.FamilialRelationship_type = Slot( + uri=PERSONINFO.type, + name="FamilialRelationship_type", + curie=PERSONINFO.curie("type"), + model_uri=PERSONINFO.FamilialRelationship_type, + domain=FamilialRelationship, + range=Union[str, "FamilialRelationshipType"], +) + +slots.FamilialRelationship_related_to = Slot( + uri=PERSONINFO.related_to, + name="FamilialRelationship_related_to", + curie=PERSONINFO.curie("related_to"), + model_uri=PERSONINFO.FamilialRelationship_related_to, + domain=FamilialRelationship, + range=Union[str, PersonId], +) diff --git a/tests/test_index/test_object_index.py b/tests/test_index/test_object_index.py index ea2d5e6e..701a3c78 100644 --- a/tests/test_index/test_object_index.py +++ b/tests/test_index/test_object_index.py @@ -1,15 +1,15 @@ import os import unittest -from linkml_runtime import SchemaView -from linkml_runtime.loaders import yaml_loader import tests.test_index.model.container_test as src_dm +from linkml_runtime import SchemaView from linkml_runtime.index.object_index import ObjectIndex, ProxyObject -from linkml_runtime.utils.inference_utils import infer_slot_value, Config +from linkml_runtime.loaders import yaml_loader +from linkml_runtime.utils.inference_utils import Config, infer_slot_value from tests.test_index import INPUT_DIR -SCHEMA = os.path.join(INPUT_DIR, 'container_test.yaml') -DATA = os.path.join(INPUT_DIR, 'object-indexer-data.yaml') +SCHEMA = os.path.join(INPUT_DIR, "container_test.yaml") +DATA = os.path.join(INPUT_DIR, "object-indexer-data.yaml") class ObjectIndexerTestCase(unittest.TestCase): @@ -23,7 +23,7 @@ def setUp(self) -> None: self.container = yaml_loader.load(DATA, target_class=src_dm.Container) def test_object_index(self): - """ checks indexing objects """ + """checks indexing objects""" # domain object container = self.container frt = container.persons[0].has_familial_relationships[0].type @@ -93,11 +93,11 @@ def test_object_index(self): self.assertEqual("P:001", oix.eval_expr("persons[0]._parents[0][1].persons[0].id")) self.assertEqual("P:001", oix.eval_expr("persons[0].persons__inverse[0].persons[0].id")) # test inference - #infer_all_slot_values(person, self.schemaview, class_name="Person") + # infer_all_slot_values(person, self.schemaview, class_name="Person") config = Config(use_expressions=True) infer_slot_value(person, "description", schemaview=self.schemaview, class_name="Person", config=config) self.assertEqual("name: fred bloggs address: 1 oak street", person.description) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/input/issue_355.py b/tests/test_issues/input/issue_355.py index 991d356c..e13c5d51 100644 --- a/tests/test_issues/input/issue_355.py +++ b/tests/test_issues/input/issue_355.py @@ -6,27 +6,27 @@ # description: # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import URIorCURIE +from linkml_runtime.utils.metamodelcore import URIorCURIE, empty_dict +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot metamodel_version = "1.7.0" # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -SCT = CurieNamespace('sct', 'http://snomed.info/id/') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +SCT = CurieNamespace("sct", "http://snomed.info/id/") DEFAULT_ = SCT # Types + # Class references class ContaineeId(URIorCURIE): pass @@ -41,10 +41,12 @@ class Container(YAMLRoot): class_name: ClassVar[str] = "container" class_model_uri: ClassVar[URIRef] = SCT.Container - entry: Optional[Union[dict[Union[str, ContaineeId], Union[dict, "Containee"]], list[Union[dict, "Containee"]]]] = empty_dict() + entry: Optional[Union[dict[Union[str, ContaineeId], Union[dict, "Containee"]], list[Union[dict, "Containee"]]]] = ( + empty_dict() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): - self._normalize_inlined_as_dict(slot_name="entry", slot_type=Containee, key_name="id", keyed=True) + self._normalize_inlined_as_dict(slot_name="entry", slot_type=Containee, key_name="id", keyed=True) super().__post_init__(**kwargs) @@ -80,11 +82,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.container__entry = Slot(uri=SCT.entry, name="container__entry", curie=SCT.curie('entry'), - model_uri=SCT.container__entry, domain=None, range=Optional[Union[dict[Union[str, ContaineeId], Union[dict, Containee]], list[Union[dict, Containee]]]]) - -slots.containee__id = Slot(uri=SCT.id, name="containee__id", curie=SCT.curie('id'), - model_uri=SCT.containee__id, domain=None, range=URIRef) -slots.containee__value = Slot(uri=SCT.value, name="containee__value", curie=SCT.curie('value'), - model_uri=SCT.containee__value, domain=None, range=Optional[str]) +slots.container__entry = Slot( + uri=SCT.entry, + name="container__entry", + curie=SCT.curie("entry"), + model_uri=SCT.container__entry, + domain=None, + range=Optional[Union[dict[Union[str, ContaineeId], Union[dict, Containee]], list[Union[dict, Containee]]]], +) + +slots.containee__id = Slot( + uri=SCT.id, name="containee__id", curie=SCT.curie("id"), model_uri=SCT.containee__id, domain=None, range=URIRef +) + +slots.containee__value = Slot( + uri=SCT.value, + name="containee__value", + curie=SCT.curie("value"), + model_uri=SCT.containee__value, + domain=None, + range=Optional[str], +) diff --git a/tests/test_issues/input/issue_368.py b/tests/test_issues/input/issue_368.py index 39b6d31b..60f7d9ae 100644 --- a/tests/test_issues/input/issue_368.py +++ b/tests/test_issues/input/issue_368.py @@ -6,20 +6,21 @@ # description: # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.slot import Slot + from .issue_368_imports import ParentClass, SampleEnum metamodel_version = "1.7.0" # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -DEFAULT_ = CurieNamespace('', 'https://microbiomedata/schema/') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +DEFAULT_ = CurieNamespace("", "https://microbiomedata/schema/") # Types @@ -27,7 +28,6 @@ # Class references - @dataclass class SampleClass(ParentClass): _inherited_slots: ClassVar[list[str]] = [] @@ -53,5 +53,12 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.slot_1 = Slot(uri=DEFAULT_.slot_1, name="slot_1", curie=DEFAULT_.curie('slot_1'), - model_uri=DEFAULT_.slot_1, domain=None, range=Optional[Union[str, "SampleEnum"]]) + +slots.slot_1 = Slot( + uri=DEFAULT_.slot_1, + name="slot_1", + curie=DEFAULT_.curie("slot_1"), + model_uri=DEFAULT_.slot_1, + domain=None, + range=Optional[Union[str, "SampleEnum"]], +) diff --git a/tests/test_issues/input/issue_368_imports.py b/tests/test_issues/input/issue_368_imports.py index 823524c0..13864fa0 100644 --- a/tests/test_issues/input/issue_368_imports.py +++ b/tests/test_issues/input/issue_368_imports.py @@ -6,20 +6,19 @@ # description: # license: -import dataclasses from typing import ClassVar -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue -from linkml_runtime.utils.yamlutils import YAMLRoot -from linkml_runtime.utils.enumerations import EnumDefinitionImpl from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.yamlutils import YAMLRoot metamodel_version = "1.7.0" # Namespaces -DEFAULT_ = CurieNamespace('', 'https://microbiomedata/schema/mixs/') +DEFAULT_ = CurieNamespace("", "https://microbiomedata/schema/mixs/") # Types @@ -27,7 +26,6 @@ # Class references - class ParentClass(YAMLRoot): _inherited_slots: ClassVar[list[str]] = [] @@ -40,16 +38,14 @@ class ParentClass(YAMLRoot): # Enumerations class SampleEnum(EnumDefinitionImpl): - pva = PermissibleValue(text="pva", - description="PVA description") - pvb = PermissibleValue(text="pvb", - description="PVB description") + pva = PermissibleValue(text="pva", description="PVA description") + pvb = PermissibleValue(text="pvb", description="PVB description") _defn = EnumDefinition( name="SampleEnum", ) + # Slots class slots: pass - diff --git a/tests/test_issues/models/linkml_issue_576.py b/tests/test_issues/models/linkml_issue_576.py index 0b7bf1f9..68bd953d 100644 --- a/tests/test_issues/models/linkml_issue_576.py +++ b/tests/test_issues/models/linkml_issue_576.py @@ -6,33 +6,33 @@ # description: # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace + from linkml_runtime.linkml_model.types import String -from linkml_runtime.utils.metamodelcore import URIorCURIE +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.metamodelcore import URIorCURIE, empty_dict, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" version = None # Namespaces -EX = CurieNamespace('ex', 'https://example.org/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -PERSONINFO = CurieNamespace('personinfo', 'https://w3id.org/linkml/personinfo/') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +EX = CurieNamespace("ex", "https://example.org/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +PERSONINFO = CurieNamespace("personinfo", "https://w3id.org/linkml/personinfo/") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = PERSONINFO # Types class Code(String): - """ An identifier that is encoded in a string. This is used to represent identifiers that are not URIs, but are encoded as strings. For example, a person's social security number is an encoded identifier. """ + """An identifier that is encoded in a string. This is used to represent identifiers that are not URIs, but are encoded as strings. For example, a person's social security number is an encoded identifier.""" + type_class_uri = XSD.string type_class_curie = "xsd:string" type_name = "Code" @@ -149,7 +149,9 @@ class Dataset(YAMLRoot): source: Optional[Union[str, URIorCURIE]] = None persons: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = empty_dict() - organizations: Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]] = empty_dict() + organizations: Optional[ + Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]] + ] = empty_dict() pets: Optional[Union[dict[Union[str, PetId], Union[dict, Pet]], list[Union[dict, Pet]]]] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): @@ -172,41 +174,120 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.person__id = Slot(uri=PERSONINFO.id, name="person__id", curie=PERSONINFO.curie('id'), - model_uri=PERSONINFO.person__id, domain=None, range=URIRef) - -slots.person__name = Slot(uri=SCHEMA.name, name="person__name", curie=SCHEMA.curie('name'), - model_uri=PERSONINFO.person__name, domain=None, range=Optional[str]) - -slots.person__friends = Slot(uri=PERSONINFO.friends, name="person__friends", curie=PERSONINFO.curie('friends'), - model_uri=PERSONINFO.person__friends, domain=None, range=Optional[Union[Union[str, PersonId], list[Union[str, PersonId]]]]) - -slots.pet__id = Slot(uri=PERSONINFO.id, name="pet__id", curie=PERSONINFO.curie('id'), - model_uri=PERSONINFO.pet__id, domain=None, range=URIRef) - -slots.pet__name = Slot(uri=SCHEMA.name, name="pet__name", curie=SCHEMA.curie('name'), - model_uri=PERSONINFO.pet__name, domain=None, range=Optional[str]) - -slots.pet__owner = Slot(uri=SCHEMA.owner, name="pet__owner", curie=SCHEMA.curie('owner'), - model_uri=PERSONINFO.pet__owner, domain=None, range=Optional[Union[str, PersonId]]) - -slots.organization__id = Slot(uri=PERSONINFO.id, name="organization__id", curie=PERSONINFO.curie('id'), - model_uri=PERSONINFO.organization__id, domain=None, range=URIRef) - -slots.organization__name = Slot(uri=SCHEMA.name, name="organization__name", curie=SCHEMA.curie('name'), - model_uri=PERSONINFO.organization__name, domain=None, range=Optional[str]) - -slots.organization__part_of = Slot(uri=PERSONINFO.part_of, name="organization__part_of", curie=PERSONINFO.curie('part_of'), - model_uri=PERSONINFO.organization__part_of, domain=None, range=Optional[Union[Union[str, OrganizationId], list[Union[str, OrganizationId]]]]) - -slots.dataset__source = Slot(uri=PERSONINFO.source, name="dataset__source", curie=PERSONINFO.curie('source'), - model_uri=PERSONINFO.dataset__source, domain=None, range=Optional[Union[str, URIorCURIE]]) - -slots.dataset__persons = Slot(uri=PERSONINFO.persons, name="dataset__persons", curie=PERSONINFO.curie('persons'), - model_uri=PERSONINFO.dataset__persons, domain=None, range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]]) - -slots.dataset__organizations = Slot(uri=PERSONINFO.organizations, name="dataset__organizations", curie=PERSONINFO.curie('organizations'), - model_uri=PERSONINFO.dataset__organizations, domain=None, range=Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]]) -slots.dataset__pets = Slot(uri=PERSONINFO.pets, name="dataset__pets", curie=PERSONINFO.curie('pets'), - model_uri=PERSONINFO.dataset__pets, domain=None, range=Optional[Union[dict[Union[str, PetId], Union[dict, Pet]], list[Union[dict, Pet]]]]) +slots.person__id = Slot( + uri=PERSONINFO.id, + name="person__id", + curie=PERSONINFO.curie("id"), + model_uri=PERSONINFO.person__id, + domain=None, + range=URIRef, +) + +slots.person__name = Slot( + uri=SCHEMA.name, + name="person__name", + curie=SCHEMA.curie("name"), + model_uri=PERSONINFO.person__name, + domain=None, + range=Optional[str], +) + +slots.person__friends = Slot( + uri=PERSONINFO.friends, + name="person__friends", + curie=PERSONINFO.curie("friends"), + model_uri=PERSONINFO.person__friends, + domain=None, + range=Optional[Union[Union[str, PersonId], list[Union[str, PersonId]]]], +) + +slots.pet__id = Slot( + uri=PERSONINFO.id, + name="pet__id", + curie=PERSONINFO.curie("id"), + model_uri=PERSONINFO.pet__id, + domain=None, + range=URIRef, +) + +slots.pet__name = Slot( + uri=SCHEMA.name, + name="pet__name", + curie=SCHEMA.curie("name"), + model_uri=PERSONINFO.pet__name, + domain=None, + range=Optional[str], +) + +slots.pet__owner = Slot( + uri=SCHEMA.owner, + name="pet__owner", + curie=SCHEMA.curie("owner"), + model_uri=PERSONINFO.pet__owner, + domain=None, + range=Optional[Union[str, PersonId]], +) + +slots.organization__id = Slot( + uri=PERSONINFO.id, + name="organization__id", + curie=PERSONINFO.curie("id"), + model_uri=PERSONINFO.organization__id, + domain=None, + range=URIRef, +) + +slots.organization__name = Slot( + uri=SCHEMA.name, + name="organization__name", + curie=SCHEMA.curie("name"), + model_uri=PERSONINFO.organization__name, + domain=None, + range=Optional[str], +) + +slots.organization__part_of = Slot( + uri=PERSONINFO.part_of, + name="organization__part_of", + curie=PERSONINFO.curie("part_of"), + model_uri=PERSONINFO.organization__part_of, + domain=None, + range=Optional[Union[Union[str, OrganizationId], list[Union[str, OrganizationId]]]], +) + +slots.dataset__source = Slot( + uri=PERSONINFO.source, + name="dataset__source", + curie=PERSONINFO.curie("source"), + model_uri=PERSONINFO.dataset__source, + domain=None, + range=Optional[Union[str, URIorCURIE]], +) + +slots.dataset__persons = Slot( + uri=PERSONINFO.persons, + name="dataset__persons", + curie=PERSONINFO.curie("persons"), + model_uri=PERSONINFO.dataset__persons, + domain=None, + range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]], +) + +slots.dataset__organizations = Slot( + uri=PERSONINFO.organizations, + name="dataset__organizations", + curie=PERSONINFO.curie("organizations"), + model_uri=PERSONINFO.dataset__organizations, + domain=None, + range=Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]], +) + +slots.dataset__pets = Slot( + uri=PERSONINFO.pets, + name="dataset__pets", + curie=PERSONINFO.curie("pets"), + model_uri=PERSONINFO.dataset__pets, + domain=None, + range=Optional[Union[dict[Union[str, PetId], Union[dict, Pet]], list[Union[dict, Pet]]]], +) diff --git a/tests/test_issues/models/model_817.py b/tests/test_issues/models/model_817.py index 874a9162..d33d0ca2 100644 --- a/tests/test_issues/models/model_817.py +++ b/tests/test_issues/models/model_817.py @@ -6,34 +6,35 @@ # description: # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str -from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from jsonasobj2 import as_dict from rdflib import URIRef + +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import empty_dict, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" version = None # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -PERSONINFO = CurieNamespace('personinfo', 'https://w3id.org/linkml/examples/personinfo/') -RDF = CurieNamespace('rdf', 'http://example.org/UNKNOWN/rdf/') -RDFS = CurieNamespace('rdfs', 'http://example.org/UNKNOWN/rdfs/') -SKOS = CurieNamespace('skos', 'http://example.org/UNKNOWN/skos/') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +PERSONINFO = CurieNamespace("personinfo", "https://w3id.org/linkml/examples/personinfo/") +RDF = CurieNamespace("rdf", "http://example.org/UNKNOWN/rdf/") +RDFS = CurieNamespace("rdfs", "http://example.org/UNKNOWN/rdfs/") +SKOS = CurieNamespace("skos", "http://example.org/UNKNOWN/skos/") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = PERSONINFO # Types + # Class references class PersonId(extended_str): pass @@ -99,8 +100,12 @@ class Container(YAMLRoot): class_model_uri: ClassVar[URIRef] = PERSONINFO.Container name: Optional[str] = None - persons_as_list: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = empty_dict() - persons_as_dict: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = empty_dict() + persons_as_list: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = ( + empty_dict() + ) + persons_as_dict: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = ( + empty_dict() + ) single_person_inlined: Optional[Union[dict, Person]] = None noidobj_as_list: Optional[Union[Union[dict, PersonNoId], list[Union[dict, PersonNoId]]]] = empty_list() single_noidobj_inlined: Optional[Union[dict, PersonNoId]] = None @@ -118,7 +123,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.noidobj_as_list, list): self.noidobj_as_list = [self.noidobj_as_list] if self.noidobj_as_list is not None else [] - self.noidobj_as_list = [v if isinstance(v, PersonNoId) else PersonNoId(**as_dict(v)) for v in self.noidobj_as_list] + self.noidobj_as_list = [ + v if isinstance(v, PersonNoId) else PersonNoId(**as_dict(v)) for v in self.noidobj_as_list + ] if self.single_noidobj_inlined is not None and not isinstance(self.single_noidobj_inlined, PersonNoId): self.single_noidobj_inlined = PersonNoId(**as_dict(self.single_noidobj_inlined)) @@ -136,30 +143,75 @@ class VitalStatusEnum(EnumDefinitionImpl): name="VitalStatusEnum", ) + # Slots class slots: pass -slots.id = Slot(uri=PERSONINFO.id, name="id", curie=PERSONINFO.curie('id'), - model_uri=PERSONINFO.id, domain=None, range=URIRef) - -slots.name = Slot(uri=PERSONINFO.name, name="name", curie=PERSONINFO.curie('name'), - model_uri=PERSONINFO.name, domain=None, range=Optional[str]) - -slots.persons_as_list = Slot(uri=PERSONINFO.persons_as_list, name="persons_as_list", curie=PERSONINFO.curie('persons_as_list'), - model_uri=PERSONINFO.persons_as_list, domain=None, range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]]) - -slots.persons_as_dict = Slot(uri=PERSONINFO.persons_as_dict, name="persons_as_dict", curie=PERSONINFO.curie('persons_as_dict'), - model_uri=PERSONINFO.persons_as_dict, domain=None, range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]]) - -slots.single_person_inlined = Slot(uri=PERSONINFO.single_person_inlined, name="single_person_inlined", curie=PERSONINFO.curie('single_person_inlined'), - model_uri=PERSONINFO.single_person_inlined, domain=None, range=Optional[Union[dict, Person]]) - -slots.noidobj_as_list = Slot(uri=PERSONINFO.noidobj_as_list, name="noidobj_as_list", curie=PERSONINFO.curie('noidobj_as_list'), - model_uri=PERSONINFO.noidobj_as_list, domain=None, range=Optional[Union[Union[dict, PersonNoId], list[Union[dict, PersonNoId]]]]) - -slots.single_noidobj_inlined = Slot(uri=PERSONINFO.single_noidobj_inlined, name="single_noidobj_inlined", curie=PERSONINFO.curie('single_noidobj_inlined'), - model_uri=PERSONINFO.single_noidobj_inlined, domain=None, range=Optional[Union[dict, PersonNoId]]) -slots.vital_status = Slot(uri=PERSONINFO.vital_status, name="vital_status", curie=PERSONINFO.curie('vital_status'), - model_uri=PERSONINFO.vital_status, domain=None, range=Optional[Union[str, "VitalStatusEnum"]]) +slots.id = Slot( + uri=PERSONINFO.id, name="id", curie=PERSONINFO.curie("id"), model_uri=PERSONINFO.id, domain=None, range=URIRef +) + +slots.name = Slot( + uri=PERSONINFO.name, + name="name", + curie=PERSONINFO.curie("name"), + model_uri=PERSONINFO.name, + domain=None, + range=Optional[str], +) + +slots.persons_as_list = Slot( + uri=PERSONINFO.persons_as_list, + name="persons_as_list", + curie=PERSONINFO.curie("persons_as_list"), + model_uri=PERSONINFO.persons_as_list, + domain=None, + range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]], +) + +slots.persons_as_dict = Slot( + uri=PERSONINFO.persons_as_dict, + name="persons_as_dict", + curie=PERSONINFO.curie("persons_as_dict"), + model_uri=PERSONINFO.persons_as_dict, + domain=None, + range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]], +) + +slots.single_person_inlined = Slot( + uri=PERSONINFO.single_person_inlined, + name="single_person_inlined", + curie=PERSONINFO.curie("single_person_inlined"), + model_uri=PERSONINFO.single_person_inlined, + domain=None, + range=Optional[Union[dict, Person]], +) + +slots.noidobj_as_list = Slot( + uri=PERSONINFO.noidobj_as_list, + name="noidobj_as_list", + curie=PERSONINFO.curie("noidobj_as_list"), + model_uri=PERSONINFO.noidobj_as_list, + domain=None, + range=Optional[Union[Union[dict, PersonNoId], list[Union[dict, PersonNoId]]]], +) + +slots.single_noidobj_inlined = Slot( + uri=PERSONINFO.single_noidobj_inlined, + name="single_noidobj_inlined", + curie=PERSONINFO.curie("single_noidobj_inlined"), + model_uri=PERSONINFO.single_noidobj_inlined, + domain=None, + range=Optional[Union[dict, PersonNoId]], +) + +slots.vital_status = Slot( + uri=PERSONINFO.vital_status, + name="vital_status", + curie=PERSONINFO.curie("vital_status"), + model_uri=PERSONINFO.vital_status, + domain=None, + range=Optional[Union[str, "VitalStatusEnum"]], +) diff --git a/tests/test_issues/test_dataclass_extensions_376.py b/tests/test_issues/test_dataclass_extensions_376.py index 093a233e..119e0ff5 100644 --- a/tests/test_issues/test_dataclass_extensions_376.py +++ b/tests/test_issues/test_dataclass_extensions_376.py @@ -1,7 +1,7 @@ -import sys -import pytest -import importlib.util import dataclasses +import importlib.util + +import pytest def import_patch_module(): @@ -11,6 +11,7 @@ def import_patch_module(): spec.loader.exec_module(mod) return mod + def test_patch_module_emits_deprecation_warning(): """All Python versions: emits DeprecationWarning and defines compatibility symbols""" with pytest.warns(DeprecationWarning): @@ -23,5 +24,3 @@ def test_patch_module_emits_deprecation_warning(): # Check consistency with actual dataclasses module init_fn = getattr(dataclasses, "_init_fn", None) assert mod.dataclasses_init_fn_with_kwargs == init_fn - - diff --git a/tests/test_issues/test_include_schema.py b/tests/test_issues/test_include_schema.py index 1ae0c22d..588c1f17 100644 --- a/tests/test_issues/test_include_schema.py +++ b/tests/test_issues/test_include_schema.py @@ -6,12 +6,12 @@ class IncludeSchemaTestCase(unittest.TestCase): - """ include_schema.yaml produces a Python exception on an uncaught error""" + """include_schema.yaml produces a Python exception on an uncaught error""" + # "Awaiting fix for issue #3" def test_include_schema(self): - inp = yaml_loader.load(env.input_path('include_schema.yaml'), SchemaDefinition) - + inp = yaml_loader.load(env.input_path("include_schema.yaml"), SchemaDefinition) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_issue_1040.py b/tests/test_issues/test_issue_1040.py index a2a0d770..02d1e567 100644 --- a/tests/test_issues/test_issue_1040.py +++ b/tests/test_issues/test_issue_1040.py @@ -11,11 +11,12 @@ class Issue1040TestCase(TestCase): """ https://github.com/linkml/linkml/issues/1040 """ + env = env def test_issue_1040_file_name(self): - """ issue_1040.yaml has a parsing error is confusing as all getout when accompanied by a stack - trace. We use this to make sure that the file name gets in correctly. """ + """issue_1040.yaml has a parsing error is confusing as all getout when accompanied by a stack + trace. We use this to make sure that the file name gets in correctly.""" with self.assertRaises(yaml.constructor.ConstructorError) as e: - yaml_loader.load(env.input_path('issue_1040.yaml'), SchemaDefinition) + yaml_loader.load(env.input_path("issue_1040.yaml"), SchemaDefinition) self.assertIn('"issue_1040.yaml"', str(e.exception)) diff --git a/tests/test_issues/test_issue_1355.py b/tests/test_issues/test_issue_1355.py index 6175c72d..450989e2 100644 --- a/tests/test_issues/test_issue_1355.py +++ b/tests/test_issues/test_issue_1355.py @@ -1,28 +1,30 @@ -''' +""" Created on 2023-03-24 @author: wf -''' +""" + from unittest import TestCase + from linkml_runtime.utils.metamodelcore import URI + class Issue1355TestCase(TestCase): """ https://github.com/linkml/linkml/issues/1355 improve invalid URL message """ - + def test_issue_1355_invalid_url_message(self): """ check that quotes are used when referencing invalid urls so that the visiblity of the problem gets better """ - # note the trailing blank - url="https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf " + # note the trailing blank + url = "https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf " try: - _uri=URI(url) + _uri = URI(url) except ValueError as vex: - msg=str(vex) + msg = str(vex) # 'https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf ': is not a valid URI self.assertTrue(".pdf '" in msg) - diff --git a/tests/test_issues/test_issue_163.py b/tests/test_issues/test_issue_163.py index e8e2afc7..170825da 100644 --- a/tests/test_issues/test_issue_163.py +++ b/tests/test_issues/test_issue_163.py @@ -6,11 +6,11 @@ class Issue163TestCase(unittest.TestCase): def test_trailing_sep(self): - """ Test the importmap namespace """ + """Test the importmap namespace""" importmap = parse_import_map('{ "base:": "base/" }', os.path.dirname(__file__)) # TODO: see how this works in a windows environment - self.assertTrue(importmap['base:'].endswith('/'), msg="Trailing separator stripped in import map parsing") + self.assertTrue(importmap["base:"].endswith("/"), msg="Trailing separator stripped in import map parsing") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_issue_355.py b/tests/test_issues/test_issue_355.py index 4e44ad74..4d60c0f7 100644 --- a/tests/test_issues/test_issue_355.py +++ b/tests/test_issues/test_issue_355.py @@ -6,28 +6,28 @@ # description: # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from jsonasobj2 import JsonObj -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot +from jsonasobj2 import JsonObj from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import URIorCURIE +from linkml_runtime.utils.metamodelcore import URIorCURIE, empty_dict +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot metamodel_version = "1.7.0" # Namespaces -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -SCT = CurieNamespace('sct', 'http://snomed.info/id/') +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +SCT = CurieNamespace("sct", "http://snomed.info/id/") DEFAULT_ = SCT # Types + # Class references class ContaineeId(URIorCURIE): pass @@ -42,7 +42,9 @@ class Container(YAMLRoot): class_name: ClassVar[str] = "container" class_model_uri: ClassVar[URIRef] = SCT.Container - entry: Optional[Union[dict[Union[str, ContaineeId], Union[dict, "Containee"]], list[Union[dict, "Containee"]]]] = empty_dict() + entry: Optional[Union[dict[Union[str, ContaineeId], Union[dict, "Containee"]], list[Union[dict, "Containee"]]]] = ( + empty_dict() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.entry, (list, dict, JsonObj)): @@ -83,11 +85,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.container__entry = Slot(uri=SCT.entry, name="container__entry", curie=SCT.curie('entry'), - model_uri=SCT.container__entry, domain=None, range=Optional[Union[dict[Union[str, ContaineeId], Union[dict, Containee]], list[Union[dict, Containee]]]]) - -slots.containee__id = Slot(uri=SCT.id, name="containee__id", curie=SCT.curie('id'), - model_uri=SCT.containee__id, domain=None, range=URIRef) -slots.containee__value = Slot(uri=SCT.value, name="containee__value", curie=SCT.curie('value'), - model_uri=SCT.containee__value, domain=None, range=Optional[str]) +slots.container__entry = Slot( + uri=SCT.entry, + name="container__entry", + curie=SCT.curie("entry"), + model_uri=SCT.container__entry, + domain=None, + range=Optional[Union[dict[Union[str, ContaineeId], Union[dict, Containee]], list[Union[dict, Containee]]]], +) + +slots.containee__id = Slot( + uri=SCT.id, name="containee__id", curie=SCT.curie("id"), model_uri=SCT.containee__id, domain=None, range=URIRef +) + +slots.containee__value = Slot( + uri=SCT.value, + name="containee__value", + curie=SCT.curie("value"), + model_uri=SCT.containee__value, + domain=None, + range=Optional[str], +) diff --git a/tests/test_issues/test_issue_368_enums.py b/tests/test_issues/test_issue_368_enums.py index 68443146..1b189e66 100644 --- a/tests/test_issues/test_issue_368_enums.py +++ b/tests/test_issues/test_issue_368_enums.py @@ -1,40 +1,40 @@ import unittest from typing import Callable -from linkml_runtime.dumpers import json_dumper, yaml_dumper, rdf_dumper +from linkml_runtime.dumpers import json_dumper, rdf_dumper, yaml_dumper +from linkml_runtime.utils.compile_python import compile_python from tests.test_issues.environment import env from tests.test_loaders_dumpers.loaderdumpertestcase import LoaderDumperTestCase -from linkml_runtime.utils.compile_python import compile_python class Issue368TestCase(LoaderDumperTestCase): env = env def header(self, txt: str) -> str: - return '\n' + ("=" * 20) + f" {txt} " + ("=" * 20) + return "\n" + ("=" * 20) + f" {txt} " + ("=" * 20) def test_issue_368_enums(self): - """ Test Enum generation """ + """Test Enum generation""" - module = compile_python(env.input_path('issue_368.py')) + module = compile_python(env.input_path("issue_368.py")) - enum_inst = module.SampleEnum("pva") # EnumInstanceImpl + enum_inst = module.SampleEnum("pva") # EnumInstanceImpl example = module.SampleClass(slot_1="pva") assert hasattr(example, "slot_1") assert example.slot_1.code.text == enum_inst.code.text assert str(example.slot_1) == "pva" def dump_and_load(dumper: Callable, sfx: str) -> None: - fname = env.actual_path(f'issue_368_1.{sfx}') + fname = env.actual_path(f"issue_368_1.{sfx}") dumper(example, fname) with open(fname) as f: - print(f'\n----- {sfx} -----') + print(f"\n----- {sfx} -----") print(f.read()) - dump_and_load(json_dumper.dump, 'json') - dump_and_load(yaml_dumper.dump, 'yaml') - dump_and_load(lambda obj, fname: rdf_dumper.dump(obj, fname, env.input_path("issue_368.context.jsonld")), 'ttl') + dump_and_load(json_dumper.dump, "json") + dump_and_load(yaml_dumper.dump, "yaml") + dump_and_load(lambda obj, fname: rdf_dumper.dump(obj, fname, env.input_path("issue_368.context.jsonld")), "ttl") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_issue_6.py b/tests/test_issues/test_issue_6.py index bd9adb6b..1365ee17 100644 --- a/tests/test_issues/test_issue_6.py +++ b/tests/test_issues/test_issue_6.py @@ -16,22 +16,23 @@ class Issue6TestCase(unittest.TestCase): def test_loc_function(self): inp = yaml.load(hbreader.hbread(inp_yaml), DupCheckYamlLoader) - self.assertEqual('File "", line 3, col 8: ', TypedNode.yaml_loc(inp['foo']['x'])) - self.assertEqual('File "", line 3, col 8', TypedNode.yaml_loc(inp['foo']['x'], suffix='')) - self.assertEqual('File "", line 4, col 8: ', TypedNode.yaml_loc(inp['foo']['y'])) - self.assertEqual('File "", line 4, col 8I yam that I yam', - TypedNode.yaml_loc(inp['foo']['y'], suffix=inp['foo']['y'])) - self.assertEqual('File "", line 5, col 8: ', TypedNode.yaml_loc(inp['foo']['z'])) + self.assertEqual('File "", line 3, col 8: ', TypedNode.yaml_loc(inp["foo"]["x"])) + self.assertEqual('File "", line 3, col 8', TypedNode.yaml_loc(inp["foo"]["x"], suffix="")) + self.assertEqual('File "", line 4, col 8: ', TypedNode.yaml_loc(inp["foo"]["y"])) + self.assertEqual( + 'File "", line 4, col 8I yam that I yam', + TypedNode.yaml_loc(inp["foo"]["y"], suffix=inp["foo"]["y"]), + ) + self.assertEqual('File "", line 5, col 8: ', TypedNode.yaml_loc(inp["foo"]["z"])) with self.assertWarns(DeprecationWarning) as cm: - self.assertEqual('File "", line 3, col 8', TypedNode.loc(inp['foo']['x'])) - self.assertEqual('Call to deprecated method loc. (Use yaml_loc instead)', cm.warning.args[0]) + self.assertEqual('File "", line 3, col 8', TypedNode.loc(inp["foo"]["x"])) + self.assertEqual("Call to deprecated method loc. (Use yaml_loc instead)", cm.warning.args[0]) + self.assertEqual("", TypedNode.yaml_loc(None)) + self.assertEqual("", TypedNode.yaml_loc("abc")) + self.assertEqual("", TypedNode.yaml_loc(["a", "b"])) - self.assertEqual('', TypedNode.yaml_loc(None)) - self.assertEqual('', TypedNode.yaml_loc("abc")) - self.assertEqual('', TypedNode.yaml_loc(['a', 'b'])) - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_issue_626.py b/tests/test_issues/test_issue_626.py index 4b03e677..58b24379 100644 --- a/tests/test_issues/test_issue_626.py +++ b/tests/test_issues/test_issue_626.py @@ -20,13 +20,14 @@ class IsolatedNameTestCase(unittest.TestCase): def test_it(self): - """ Dangling name should not throw a type error """ + """Dangling name should not throw a type error""" error_thrown = False try: from_yaml(model_txt, SchemaDefinition) - except TypeError as e: + except TypeError: error_thrown = True self.assertFalse(error_thrown, msg="Type error should not be thrown") -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_issue_718.py b/tests/test_issues/test_issue_718.py index 5ad6e331..5f7855bd 100644 --- a/tests/test_issues/test_issue_718.py +++ b/tests/test_issues/test_issue_718.py @@ -1,13 +1,13 @@ -import pytest from dataclasses import dataclass -from typing import Optional, ClassVar +from typing import ClassVar, Optional +import pytest import yaml -from linkml_runtime.utils.yamlutils import YAMLRoot, DupCheckYamlLoader +from linkml_runtime.utils.yamlutils import DupCheckYamlLoader, YAMLRoot -@pytest.mark.xfail(reason='Reporting line numbers should happen at load time not when instantiating dataclasses') +@pytest.mark.xfail(reason="Reporting line numbers should happen at load time not when instantiating dataclasses") def test_issue_38(): # The goal is to provide line numbers on error messages. We've tweaked the parser so that it returns augmented # str's and int's with the line numbers on them. The problem we are trying to address now is that the dataclass @@ -30,12 +30,11 @@ class FesterBesterTester(YAMLRoot): c: sell""" parsed_yaml = yaml.load(yaml_str, DupCheckYamlLoader) - with pytest.raises(TypeError, match="File \"\", line 4, col 9"): - FesterBesterTester(**parsed_yaml['base']) + with pytest.raises(TypeError, match='File "", line 4, col 9'): + FesterBesterTester(**parsed_yaml["base"]) - parsed_yaml['base'].pop('c', None) + parsed_yaml["base"].pop("c", None) - instance = FesterBesterTester(**parsed_yaml['base']) + instance = FesterBesterTester(**parsed_yaml["base"]) assert instance.a == 17 assert instance.b == "Ice Cream" - diff --git a/tests/test_issues/test_issue_8.py b/tests/test_issues/test_issue_8.py index c9167743..0cc26cf2 100644 --- a/tests/test_issues/test_issue_8.py +++ b/tests/test_issues/test_issue_8.py @@ -1,6 +1,6 @@ import unittest -from linkml_runtime.linkml_model import SchemaDefinition, SlotDefinition, ClassDefinition +from linkml_runtime.linkml_model import ClassDefinition, SchemaDefinition, SlotDefinition from linkml_runtime.loaders import yaml_loader from linkml_runtime.utils.yamlutils import YAMLRoot from tests.test_issues.environment import env @@ -8,9 +8,10 @@ def override(cls: type[YAMLRoot]): orig = cls.MissingRequiredField + def mrf(self, field_name: str) -> None: if isinstance(self, SchemaDefinition) and field_name == "name" and self.id: - id_parts = self.id.replace('#', '/').rsplit('/') + id_parts = self.id.replace("#", "/").rsplit("/") self.name = id_parts[-1] elif isinstance(self, SlotDefinition) and field_name == "name": self.name = "id" @@ -18,6 +19,7 @@ def mrf(self, field_name: str) -> None: self.name = "core" else: orig(self, f"{type(self).__name__}.{field_name}") + cls.MissingRequiredField = mrf return orig @@ -28,6 +30,7 @@ def mrf(self, field_name: str) -> None: def override2(): def mrf(self, field_name: str) -> None: msgs.add(f"{type(self).__name__}.{field_name} is not supplied") + orig = YAMLRoot.MissingRequiredField YAMLRoot.MissingRequiredField = mrf return orig @@ -36,34 +39,39 @@ def mrf(self, field_name: str) -> None: class TestErrorIntercept(unittest.TestCase): def test_legitimate_error(self): - """ Test that legitimate errors are emitted correctly """ - test_file = env.input_path('issue_8a.yaml') + """Test that legitimate errors are emitted correctly""" + test_file = env.input_path("issue_8a.yaml") with self.assertRaises(ValueError) as e: yaml_loader.load(test_file, SchemaDefinition) - self.assertEqual('name must be supplied', str(e.exception), "ValueError should be raised") + self.assertEqual("name must be supplied", str(e.exception), "ValueError should be raised") orig = override(SchemaDefinition) try: with self.assertRaises(ValueError) as e: yaml_loader.load(test_file, SchemaDefinition) - self.assertEqual('SchemaDefinition.name must be supplied', str(e.exception)) + self.assertEqual("SchemaDefinition.name must be supplied", str(e.exception)) finally: # SchemaDefinition.MissingRequiredField = orig delattr(SchemaDefinition, "MissingRequiredField") def test_missing_intercept(self): - test_file = env.input_path('issue_8.yaml') + test_file = env.input_path("issue_8.yaml") with self.assertRaises(ValueError) as e: yaml_loader.load(test_file, SchemaDefinition) - self.assertEqual('name must be supplied', str(e.exception), "ValueError should be raised") + self.assertEqual("name must be supplied", str(e.exception), "ValueError should be raised") try: orig = override2() yaml_loader.load(test_file, SchemaDefinition) finally: YAMLRoot.MissingRequiredField = orig - self.assertEqual({'ClassDefinition.name is not supplied', - 'SlotDefinition.name is not supplied', - 'SchemaDefinition.name is not supplied'}, msgs) + self.assertEqual( + { + "ClassDefinition.name is not supplied", + "SlotDefinition.name is not supplied", + "SchemaDefinition.name is not supplied", + }, + msgs, + ) try: origschd = override(SchemaDefinition) @@ -79,5 +87,5 @@ def test_missing_intercept(self): # ClassDefinition.MissingRequiredField = origcd -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_linkml_issue_1126.py b/tests/test_issues/test_linkml_issue_1126.py index 93be1f6d..5d69bede 100644 --- a/tests/test_issues/test_linkml_issue_1126.py +++ b/tests/test_issues/test_linkml_issue_1126.py @@ -1,8 +1,8 @@ import unittest from unittest import TestCase -from linkml_runtime.utils.schemaview import SchemaView -from linkml_runtime.linkml_model import ClassDefinitionName +from linkml_runtime.linkml_model import ClassDefinitionName +from linkml_runtime.utils.schemaview import SchemaView from tests.test_issues.environment import env @@ -11,10 +11,11 @@ class Issue998TestCase(TestCase): https://github.com/linkml/linkml/issues/1126 Test getting classes that modify a slot """ + env = env def test_issue_1126_slot_classes(self): - view = SchemaView(env.input_path('linkml_issue_1126.yaml')) + view = SchemaView(env.input_path("linkml_issue_1126.yaml")) slot_definition = view.get_slot("type") slot_classes = view.get_classes_modifying_slot(slot_definition) assert len(slot_classes) == 2 @@ -23,5 +24,6 @@ def test_issue_1126_slot_classes(self): assert slot_classes[0] == ClassDefinitionName("Programmer") assert slot_classes[1] == ClassDefinitionName("Administrator") + if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_linkml_issue_1143.py b/tests/test_issues/test_linkml_issue_1143.py index 24e163b8..ce961bd6 100644 --- a/tests/test_issues/test_linkml_issue_1143.py +++ b/tests/test_issues/test_linkml_issue_1143.py @@ -2,31 +2,38 @@ from copy import deepcopy from unittest import TestCase -from linkml_runtime.linkml_model import SchemaDefinition, ClassDefinition, SlotDefinition, EnumDefinition, TypeDefinition, Prefix, \ - SubsetDefinition +from linkml_runtime.linkml_model import ( + ClassDefinition, + EnumDefinition, + Prefix, + SchemaDefinition, + SlotDefinition, + SubsetDefinition, + TypeDefinition, +) from linkml_runtime.utils.schemaview import SchemaView - from tests.test_issues.environment import env -ELEMENTS = ['prefixes', 'classes', 'slots', 'enums', 'types', 'subsets'] +ELEMENTS = ["prefixes", "classes", "slots", "enums", "types", "subsets"] EXPECTED = { - 'prefixes': ['sc1p1', 'sc2p1'], - 'classes': ['sc1c1', 'sc1c2', 'sc2c1', 'sc2c2'], - 'slots': ['sc1s1', 'sc1s2', 'sc2s1', 'sc2s2'], - 'enums': ['sc1e1', 'sc2e1'], - 'types': ['sc1t1', 'sc2t1'], - 'subsets': ['sc1ss1', 'sc2ss1'], - } - - -def make_schema(name: str, - prefixes: list[Prefix] = None, - classes: list[ClassDefinition] = None, - slots: list[SlotDefinition] = None, - enums: list[EnumDefinition] = None, - types: list[TypeDefinition] = None, - subsets: list[SubsetDefinition] = None, - ) -> SchemaDefinition: + "prefixes": ["sc1p1", "sc2p1"], + "classes": ["sc1c1", "sc1c2", "sc2c1", "sc2c2"], + "slots": ["sc1s1", "sc1s2", "sc2s1", "sc2s2"], + "enums": ["sc1e1", "sc2e1"], + "types": ["sc1t1", "sc2t1"], + "subsets": ["sc1ss1", "sc2ss1"], +} + + +def make_schema( + name: str, + prefixes: list[Prefix] = None, + classes: list[ClassDefinition] = None, + slots: list[SlotDefinition] = None, + enums: list[EnumDefinition] = None, + types: list[TypeDefinition] = None, + subsets: list[SubsetDefinition] = None, +) -> SchemaDefinition: """ Make a schema with the given elements @@ -60,10 +67,12 @@ def make_schema(name: str, schema.subsets[s.name] = s return schema + class Issue1143TestCase(TestCase): """ https://github.com/linkml/linkml/issues/1143 """ + env = env def make_schemas(self) -> None: @@ -76,32 +85,38 @@ def make_schemas(self) -> None: :return: """ s1 = make_schema( - 's1', - prefixes=[Prefix(prefix_prefix='sc1p1', prefix_reference='http://example.org/sc1url1')], - classes=[ClassDefinition(name='sc1c1', slots=['sc1s1']), - ClassDefinition(name='sc1c2', slots=['sc1s2'])], - slots=[SlotDefinition(name='sc1s1', range='string'), - SlotDefinition(name='sc1s2', range='float')], - enums=[EnumDefinition(name='sc1e1', - permissible_values={'sc1e1v1': 'sc1e1v1',} - )], - types=[TypeDefinition(name='sc1t1', base='string')], - subsets=[SubsetDefinition(name='sc1ss1', description='sc1ss1')], + "s1", + prefixes=[Prefix(prefix_prefix="sc1p1", prefix_reference="http://example.org/sc1url1")], + classes=[ClassDefinition(name="sc1c1", slots=["sc1s1"]), ClassDefinition(name="sc1c2", slots=["sc1s2"])], + slots=[SlotDefinition(name="sc1s1", range="string"), SlotDefinition(name="sc1s2", range="float")], + enums=[ + EnumDefinition( + name="sc1e1", + permissible_values={ + "sc1e1v1": "sc1e1v1", + }, + ) + ], + types=[TypeDefinition(name="sc1t1", base="string")], + subsets=[SubsetDefinition(name="sc1ss1", description="sc1ss1")], ) s2 = make_schema( - 's2', - prefixes=[Prefix(prefix_prefix='sc2p1', prefix_reference='http://example.org/sc2url1')], - classes=[ClassDefinition(name='sc2c1', slots=['sc2s1']), - ClassDefinition(name='sc2c2', slots=['sc2s2'])], - slots=[SlotDefinition(name='sc2s1', range='string'), - SlotDefinition(name='sc2s2', range='float')], - enums=[EnumDefinition(name='sc2e1', - permissible_values={'sc2e1v1': 'sc2e1v1',} - )], - types=[TypeDefinition(name='sc2t1', base='string')], - subsets=[SubsetDefinition(name='sc2ss1', description='sc2ss1')], + "s2", + prefixes=[Prefix(prefix_prefix="sc2p1", prefix_reference="http://example.org/sc2url1")], + classes=[ClassDefinition(name="sc2c1", slots=["sc2s1"]), ClassDefinition(name="sc2c2", slots=["sc2s2"])], + slots=[SlotDefinition(name="sc2s1", range="string"), SlotDefinition(name="sc2s2", range="float")], + enums=[ + EnumDefinition( + name="sc2e1", + permissible_values={ + "sc2e1v1": "sc2e1v1", + }, + ) + ], + types=[TypeDefinition(name="sc2t1", base="string")], + subsets=[SubsetDefinition(name="sc2ss1", description="sc2ss1")], ) - s3 = make_schema('s3') + s3 = make_schema("s3") self.sv1 = SchemaView(s1) self.sv2 = SchemaView(s2) self.sv3 = SchemaView(s3) @@ -117,8 +132,8 @@ def is_identical(self, sv1: SchemaView, sv2: SchemaView) -> None: s1 = sv1.schema s2 = sv2.schema for k in ELEMENTS: - self.assertCountEqual(getattr(s1, k).keys(), getattr(s2, k).keys(), f'{k} keys not equal') - self.assertCountEqual(getattr(s1, k).values(), getattr(s2, k).values(), f'{k} vals not equal') + self.assertCountEqual(getattr(s1, k).keys(), getattr(s2, k).keys(), f"{k} keys not equal") + self.assertCountEqual(getattr(s1, k).values(), getattr(s2, k).values(), f"{k} vals not equal") def test_merge_empty(self): """ @@ -145,12 +160,13 @@ def test_merge_schema(self): self.sv2.merge_schema(self.sv1.schema) for k, vs in EXPECTED.items(): - self.assertCountEqual(getattr(self.sv2.schema, k).keys(), vs, f'{k} keys not equal') + self.assertCountEqual(getattr(self.sv2.schema, k).keys(), vs, f"{k} keys not equal") + def _get_clobbered_field_val(self, element: str) -> tuple[str, str]: - if element == 'prefixes': - return 'prefix_reference', 'http://example.org/clobbered' + if element == "prefixes": + return "prefix_reference", "http://example.org/clobbered" else: - return 'description', 'clobbered' + return "description", "clobbered" def test_no_clobber(self): """ @@ -168,7 +184,7 @@ def test_no_clobber(self): (field, val) = self._get_clobbered_field_val(element) for k, v in getattr(self.sv2.schema, element).items(): if k in getattr(self.sv1.schema, element): - self.assertNotEqual(getattr(v, field), val, f'{element} {k} clobbered') + self.assertNotEqual(getattr(v, field), val, f"{element} {k} clobbered") def test_clobber(self): """ @@ -186,7 +202,7 @@ def test_clobber(self): (field, val) = self._get_clobbered_field_val(element) for k, v in getattr(self.sv2.schema, element).items(): if k in getattr(self.sv1.schema, element): - self.assertEqual(getattr(v, field), val, f'{element} {k} not clobbered') + self.assertEqual(getattr(v, field), val, f"{element} {k} not clobbered") if __name__ == "__main__": diff --git a/tests/test_issues/test_linkml_issue_478.py b/tests/test_issues/test_linkml_issue_478.py index 96a3ce6c..61032d63 100644 --- a/tests/test_issues/test_linkml_issue_478.py +++ b/tests/test_issues/test_linkml_issue_478.py @@ -1,7 +1,7 @@ import unittest from unittest import TestCase -from linkml_runtime.utils.schemaview import SchemaView +from linkml_runtime.utils.schemaview import SchemaView from tests.test_issues.environment import env @@ -9,22 +9,21 @@ class Issue478TestCase(TestCase): """ https://github.com/linkml/linkml/issues/478 """ + env = env def test_issue_478(self): - view = SchemaView(env.input_path('linkml_issue_478.yaml')) + view = SchemaView(env.input_path("linkml_issue_478.yaml")) for c in view.all_classes(): - print(f'c={c}') + print(f"c={c}") cnames = list(view.class_name_mappings().keys()) snames = list(view.slot_name_mappings().keys()) print(cnames) print(snames) cnames.remove("5'Sequencing") ## TODO - self.assertCountEqual(['FooBar', 'NamedThing', 'BiosampleProcessing', 'TooMuchWhitespace'], cnames) + self.assertCountEqual(["FooBar", "NamedThing", "BiosampleProcessing", "TooMuchWhitespace"], cnames) snames.remove("5'_sequence") ## TODO - self.assertCountEqual(['id', 'preferred_label', 'SOURCE', 'processingMethod'], snames) - - + self.assertCountEqual(["id", "preferred_label", "SOURCE", "processingMethod"], snames) if __name__ == "__main__": diff --git a/tests/test_issues/test_linkml_issue_576.py b/tests/test_issues/test_linkml_issue_576.py index 019a3038..cf63bcd5 100644 --- a/tests/test_issues/test_linkml_issue_576.py +++ b/tests/test_issues/test_linkml_issue_576.py @@ -4,43 +4,55 @@ import rdflib from linkml_runtime.dumpers import rdflib_dumper -from linkml_runtime.loaders import yaml_loader, rdflib_loader +from linkml_runtime.loaders import rdflib_loader, yaml_loader from linkml_runtime.utils.schemaview import SchemaView - from tests.test_issues.environment import env from tests.test_issues.models.linkml_issue_576 import Dataset + class Issue576TestCase(TestCase): """ https://github.com/linkml/linkml/issues/576 """ + env = env def test_issue_no_namespace(self): - view = SchemaView(env.input_path('linkml_issue_576.yaml')) - inst = yaml_loader.load(env.input_path('linkml_issue_576_data.yaml'), target_class=Dataset) - s = rdflib_dumper.dumps(inst, view, 'turtle', prefix_map={"@base": "http://example.org/default/"}) + view = SchemaView(env.input_path("linkml_issue_576.yaml")) + inst = yaml_loader.load(env.input_path("linkml_issue_576_data.yaml"), target_class=Dataset) + s = rdflib_dumper.dumps(inst, view, "turtle", prefix_map={"@base": "http://example.org/default/"}) self.assertIn("@base .", s) - g = rdflib.Graph().parse(data=s, format='turtle') + g = rdflib.Graph().parse(data=s, format="turtle") for t in g.triples((None, None, None)): print(t) cases = [ - (None, - rdflib.term.URIRef('https://w3id.org/linkml/personinfo/source'), - rdflib.term.Literal('ex:source', - datatype=rdflib.term.URIRef('http://www.w3.org/2001/XMLSchema#anyURI'))), - (None, - rdflib.term.URIRef('https://w3id.org/linkml/personinfo/pets'), - rdflib.term.URIRef('https://example.org/PetA')), - (rdflib.term.URIRef('http://example.org/default/org%201'), - rdflib.term.URIRef('http://schema.org/name'), - rdflib.term.Literal('Acme Inc. (US)')), - (rdflib.term.URIRef('https://example.org/P1'), - rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), - rdflib.term.URIRef('http://schema.org/Person')), - (rdflib.term.URIRef('https://example.org/P1'), - rdflib.term.URIRef('http://schema.org/name'), - rdflib.term.Literal('John Doe')), + ( + None, + rdflib.term.URIRef("https://w3id.org/linkml/personinfo/source"), + rdflib.term.Literal( + "ex:source", datatype=rdflib.term.URIRef("http://www.w3.org/2001/XMLSchema#anyURI") + ), + ), + ( + None, + rdflib.term.URIRef("https://w3id.org/linkml/personinfo/pets"), + rdflib.term.URIRef("https://example.org/PetA"), + ), + ( + rdflib.term.URIRef("http://example.org/default/org%201"), + rdflib.term.URIRef("http://schema.org/name"), + rdflib.term.Literal("Acme Inc. (US)"), + ), + ( + rdflib.term.URIRef("https://example.org/P1"), + rdflib.term.URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), + rdflib.term.URIRef("http://schema.org/Person"), + ), + ( + rdflib.term.URIRef("https://example.org/P1"), + rdflib.term.URIRef("http://schema.org/name"), + rdflib.term.Literal("John Doe"), + ), ] for case in cases: s, p, o = case @@ -49,7 +61,7 @@ def test_issue_no_namespace(self): else: self.assertIn(case, g) inst2 = rdflib_loader.load(g, target_class=Dataset, schemaview=view) - #print(yaml_dumper.dumps(inst2)) + # print(yaml_dumper.dumps(inst2)) self.assertCountEqual(inst.persons, inst2.persons) self.assertCountEqual(inst.organizations, inst2.organizations) self.assertCountEqual(inst.pets, inst2.pets) diff --git a/tests/test_issues/test_linkml_issue_590.py b/tests/test_issues/test_linkml_issue_590.py index e2b92b37..defadf94 100644 --- a/tests/test_issues/test_linkml_issue_590.py +++ b/tests/test_issues/test_linkml_issue_590.py @@ -1,10 +1,9 @@ import unittest from linkml_runtime.utils.schemaview import SchemaView - from tests.test_issues.environment import env -SCHEMA = env.input_path('test_linkml_issue_590.yaml') +SCHEMA = env.input_path("test_linkml_issue_590.yaml") class Issue590TestCase(unittest.TestCase): @@ -15,8 +14,8 @@ def test_issue_590(self): sv = SchemaView(SCHEMA) # check that multivalued is set to False as in schema - self.assertEqual(sv.get_slot('a').multivalued, False) + self.assertEqual(sv.get_slot("a").multivalued, False) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_linkml_issue_817.py b/tests/test_issues/test_linkml_issue_817.py index 9cf0d1e1..5178b5c3 100644 --- a/tests/test_issues/test_linkml_issue_817.py +++ b/tests/test_issues/test_linkml_issue_817.py @@ -2,9 +2,8 @@ from linkml_runtime.dumpers import yaml_dumper from linkml_runtime.loaders import yaml_loader - from tests.test_issues.environment import env -from tests.test_issues.models.model_817 import Container, Person, VitalStatusEnum, PersonNoId +from tests.test_issues.models.model_817 import Container, Person, PersonNoId, VitalStatusEnum class Issue817TestCase(unittest.TestCase): @@ -18,18 +17,18 @@ def _roundtrip(self, c: Container): self.assertCountEqual(c2.noidobj_as_list, c.noidobj_as_list) def test_issue_817(self): - person = Person(id='x', name='x', vital_status=VitalStatusEnum('LIVING')) - person2 = Person(id='y', name='y', vital_status=VitalStatusEnum('DEAD')) - thing = PersonNoId(name='z', vital_status=VitalStatusEnum('LIVING')) - c = Container(persons_as_list=[person, person2], - persons_as_dict={person.id: person, person2.id: person2}, - single_person_inlined=person, - noidobj_as_list=[thing], - single_noidobj_inlined=thing) + person = Person(id="x", name="x", vital_status=VitalStatusEnum("LIVING")) + person2 = Person(id="y", name="y", vital_status=VitalStatusEnum("DEAD")) + thing = PersonNoId(name="z", vital_status=VitalStatusEnum("LIVING")) + c = Container( + persons_as_list=[person, person2], + persons_as_dict={person.id: person, person2.id: person2}, + single_person_inlined=person, + noidobj_as_list=[thing], + single_noidobj_inlined=thing, + ) self._roundtrip(c) - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_issues/test_linkml_issue_998.py b/tests/test_issues/test_linkml_issue_998.py index b847c762..26521a93 100644 --- a/tests/test_issues/test_linkml_issue_998.py +++ b/tests/test_issues/test_linkml_issue_998.py @@ -1,4 +1,5 @@ import pytest + from linkml_runtime.utils.schemaview import SchemaView schema = """ diff --git a/tests/test_issues/test_linkml_runtime_issue_1317.py b/tests/test_issues/test_linkml_runtime_issue_1317.py index 1ca6698e..a03fbaae 100644 --- a/tests/test_issues/test_linkml_runtime_issue_1317.py +++ b/tests/test_issues/test_linkml_runtime_issue_1317.py @@ -1,11 +1,16 @@ import unittest + from linkml_runtime import SchemaView -URL = ("https://raw.githubusercontent.com/linkml/linkml-runtime/" - "2a46c65fe2e7db08e5e524342e5ff2ffb94bec92/tests/test_utils/input/kitchen_sink.yaml") +URL = ( + "https://raw.githubusercontent.com/linkml/linkml-runtime/" + "2a46c65fe2e7db08e5e524342e5ff2ffb94bec92/tests/test_utils/input/kitchen_sink.yaml" +) -MIXS_URL = ("https://raw.githubusercontent.com/GenomicsStandardsConsortium/mixs/" - "83be82a99d0a210e83b371b20b3dadb6423ec612/model/schema/mixs.yaml") +MIXS_URL = ( + "https://raw.githubusercontent.com/GenomicsStandardsConsortium/mixs/" + "83be82a99d0a210e83b371b20b3dadb6423ec612/model/schema/mixs.yaml" +) class TestRemoteModularSchemaView(unittest.TestCase): @@ -51,4 +56,4 @@ def test_mixs(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/tests/test_issues/test_linkml_runtime_issue_68.py b/tests/test_issues/test_linkml_runtime_issue_68.py index 859bbb27..083d95ce 100644 --- a/tests/test_issues/test_linkml_runtime_issue_68.py +++ b/tests/test_issues/test_linkml_runtime_issue_68.py @@ -1,6 +1,7 @@ import logging import unittest from unittest import TestCase + from linkml_runtime.utils.schemaview import SchemaView logger = logging.getLogger(__name__) @@ -76,52 +77,52 @@ class Issue68TestCase(TestCase): """ Note: linkml-runtime issue 68 was moved to https://github.com/linkml/linkml/issues/479 """ + def test_issue_68(self): view = SchemaView(schema_str) # test descripton for slot1 s1 = view.get_slot("slot1") assert s1.description == "non-induced slot1" - assert s1.range == 'class0' + assert s1.range == "class0" s2 = view.get_slot("slot2") assert not s2.required - assert s2.range == 'class0' + assert s2.range == "class0" s2_induced = view.induced_slot("slot2", "class1") assert s2_induced.required - assert s2_induced.range == 'class1' + assert s2_induced.range == "class1" # test description for slot2 # this behavior is expected see: https://github.com/linkml/linkml-runtime/issues/68 logger.info(f"s2_induced.description: {s2_induced.description}") assert s2_induced.description == "induced slot2" - s2_induced_c2 = view.induced_slot('slot2', 'class2') + s2_induced_c2 = view.induced_slot("slot2", "class2") assert s2_induced_c2.required logger.info(f"s2_induced_c2.description: {s2_induced_c2.description}") assert s2_induced_c2.description == "induced slot2" - assert s2_induced.range == 'class1' + assert s2_induced.range == "class1" - s3_induced_c2 = view.induced_slot('slot3', 'class2') + s3_induced_c2 = view.induced_slot("slot3", "class2") assert not s3_induced_c2.required - assert s3_induced_c2.description == None - assert s3_induced_c2.range == 'class0' + assert s3_induced_c2.description is None + assert s3_induced_c2.range == "class0" # mixins take priority over is-a # mixins specified in order of priority - s2_induced_c2_1a = view.induced_slot('slot2', 'class2_1a') + s2_induced_c2_1a = view.induced_slot("slot2", "class2_1a") assert not s2_induced_c2_1a.required logger.info(f"s2_induced_c2_1a.description: {s2_induced_c2_1a.description}") assert s2_induced_c2_1a.description == "mixin slot2" - assert s2_induced_c2_1a.range == 'mixin1a' + assert s2_induced_c2_1a.range == "mixin1a" - s2_induced_c2_1b = view.induced_slot('slot2', 'class2_1b') + s2_induced_c2_1b = view.induced_slot("slot2", "class2_1b") assert not s2_induced_c2_1b.required logger.info(f"s2_induced_c2_1a.description: {s2_induced_c2_1b.description}") assert s2_induced_c2_1b.description == "mixin slot2" - assert s2_induced_c2_1b.range == 'mixin1b' - + assert s2_induced_c2_1b.range == "mixin1b" if __name__ == "__main__": diff --git a/tests/test_linkml_model/test_linkml_files.py b/tests/test_linkml_model/test_linkml_files.py index 854c55e4..61cf913f 100644 --- a/tests/test_linkml_model/test_linkml_files.py +++ b/tests/test_linkml_model/test_linkml_files.py @@ -1,81 +1,76 @@ -import pytest -import requests -from pathlib import Path +from importlib.util import find_spec from itertools import product +from pathlib import Path from urllib.parse import urlparse -from importlib.util import find_spec -HAVE_REQUESTS_CACHE = bool(find_spec("requests_cache")) +import pytest +import requests from linkml_runtime.linkml_model.linkml_files import ( - Source, - Format, - _Path, - URL_FOR, - LOCAL_PATH_FOR, - LOCAL_BASE, GITHUB_IO_PATH_FOR, GITHUB_PATH_FOR, + LOCAL_BASE, + LOCAL_PATH_FOR, META_ONLY, - ReleaseTag + URL_FOR, + Format, + ReleaseTag, + Source, + _Path, ) +HAVE_REQUESTS_CACHE = bool(find_spec("requests_cache")) + + EXPECTED_FORMATS = [ - (source, fmt) for source, fmt in product(Source, Format) - if (fmt not in META_ONLY or source == Source.META) + (source, fmt) for source, fmt in product(Source, Format) if (fmt not in META_ONLY or source == Source.META) ] W3ID_EXTENSIONS = ( - 'html', - 'yaml', - 'graphql', - 'context.json', - 'context.jsonld', - 'schema.json', - 'json', - 'ttl', - 'owl', - 'shex', - 'shexc', - 'shexj' + "html", + "yaml", + "graphql", + "context.json", + "context.jsonld", + "schema.json", + "json", + "ttl", + "owl", + "shex", + "shexc", + "shexj", ) -W3ID_FORMATS = [ - (source, fmt) for source, fmt in EXPECTED_FORMATS - if _Path.get(fmt.name).extension in W3ID_EXTENSIONS -] +W3ID_FORMATS = [(source, fmt) for source, fmt in EXPECTED_FORMATS if _Path.get(fmt.name).extension in W3ID_EXTENSIONS] """The formats that have rewrite rules at https://github.com/perma-id/w3id.org/blob/master/linkml/.htaccess""" -@pytest.mark.parametrize( - 'source,fmt', - EXPECTED_FORMATS -) + +@pytest.mark.parametrize("source,fmt", EXPECTED_FORMATS) def test_local_paths(source, fmt): a_path = Path(LOCAL_PATH_FOR(source, fmt)) assert a_path.exists() assert a_path.is_absolute() -@pytest.mark.parametrize( - 'fmt', - Format.__iter__() -) + +@pytest.mark.parametrize("fmt", Format.__iter__()) def test_format_paths(fmt): """Every format should have an entry in _Path""" assert fmt.name in _Path.items() + def test_no_unmapped_dirs(): """ There should be no additional directories that don't have a mapping for Format. """ - EXCLUDES = ('__pycache__',) + EXCLUDES = ("__pycache__",) expected = {LOCAL_BASE / _Path.get(fmt.name).path for fmt in Format} - expected.add(LOCAL_BASE / 'model') + expected.add(LOCAL_BASE / "model") actual = {a_dir for a_dir in LOCAL_BASE.iterdir() if a_dir.is_dir() and a_dir.name not in EXCLUDES} # Special case the root directory actual.add(LOCAL_BASE) # Special case YAML which is in a subdirectory - we've checked for existence above - actual.add(LOCAL_BASE / _Path.get('YAML').path) + actual.add(LOCAL_BASE / _Path.get("YAML").path) assert expected == actual @@ -83,30 +78,19 @@ def test_no_unmapped_dirs(): # URLs # -------------------------------------------------- + @pytest.mark.skip("github paths largely unused and expensive to test due to ratelimiting") -@pytest.mark.parametrize( - 'release_type', - ReleaseTag.__iter__() -) -@pytest.mark.parametrize( - 'source,fmt', - EXPECTED_FORMATS -) -def test_github_path_exists(source,fmt, release_type): +@pytest.mark.parametrize("release_type", ReleaseTag.__iter__()) +@pytest.mark.parametrize("source,fmt", EXPECTED_FORMATS) +def test_github_path_exists(source, fmt, release_type): url = GITHUB_PATH_FOR(source, fmt, release_type) res = requests.get(url) assert res.status_code != 404, url -@pytest.mark.parametrize( - 'release_type', - ReleaseTag.__iter__() -) -@pytest.mark.parametrize( - 'source,fmt', - EXPECTED_FORMATS -) -def test_github_path_format(source,fmt, release_type): +@pytest.mark.parametrize("release_type", ReleaseTag.__iter__()) +@pytest.mark.parametrize("source,fmt", EXPECTED_FORMATS) +def test_github_path_format(source, fmt, release_type): if release_type == ReleaseTag.CURRENT: pytest.skip("Need to cache network requests for this") @@ -114,39 +98,28 @@ def test_github_path_format(source,fmt, release_type): # ensure it parses assert urlparse(url) # for windows... - assert '\\' not in url + assert "\\" not in url + @pytest.mark.skip("github paths largely unused") -@pytest.mark.parametrize( - 'source,fmt', - EXPECTED_FORMATS -) -def test_github_io_path(source,fmt): +@pytest.mark.parametrize("source,fmt", EXPECTED_FORMATS) +def test_github_io_path(source, fmt): url = GITHUB_IO_PATH_FOR(source, fmt) res = requests.get(url) assert res.status_code != 404, url -@pytest.mark.skipif(not HAVE_REQUESTS_CACHE,reason= 'Need to cache this') -@pytest.mark.parametrize( - 'source,fmt', - W3ID_FORMATS -) -def test_url_for_format(source,fmt): +@pytest.mark.skipif(not HAVE_REQUESTS_CACHE, reason="Need to cache this") +@pytest.mark.parametrize("source,fmt", W3ID_FORMATS) +def test_url_for_format(source, fmt): url = URL_FOR(source, fmt) res = requests.get(url) assert res.status_code != 404, url + def test_fixed_meta_url(): """ One fixed canary value - the METAMODEL_URI as used in linkml main shouldn't change """ - assert URL_FOR(Source.META, Format.YAML) == 'https://w3id.org/linkml/meta.yaml' - assert URL_FOR(Source.META, Format.JSONLD) == 'https://w3id.org/linkml/meta.context.jsonld' - - - - - - - + assert URL_FOR(Source.META, Format.YAML) == "https://w3id.org/linkml/meta.yaml" + assert URL_FOR(Source.META, Format.JSONLD) == "https://w3id.org/linkml/meta.context.jsonld" diff --git a/tests/test_loaders_dumpers/__init__.py b/tests/test_loaders_dumpers/__init__.py index 1e7b480a..d86898be 100644 --- a/tests/test_loaders_dumpers/__init__.py +++ b/tests/test_loaders_dumpers/__init__.py @@ -1,23 +1,23 @@ import os +from pathlib import Path from rdflib import Namespace -from pathlib import Path HTTP_TEST_PORT = 8000 HTTPS_TEST_PORT = 8443 TESTING_DIR = os.path.abspath(os.path.dirname(__file__)) -INPUT_DIR = os.path.join(TESTING_DIR, 'input') -OUTPUT_DIR = os.path.join(TESTING_DIR, 'output') +INPUT_DIR = os.path.join(TESTING_DIR, "input") +OUTPUT_DIR = os.path.join(TESTING_DIR, "output") -LD_10_DIR = os.path.join(TESTING_DIR, 'jsonld_context/jsonld_10/') -LD_11_DIR = os.path.join(TESTING_DIR, 'jsonld_context/jsonld_11/') +LD_10_DIR = os.path.join(TESTING_DIR, "jsonld_context/jsonld_10/") +LD_11_DIR = os.path.join(TESTING_DIR, "jsonld_context/jsonld_11/") -GITHUB_DIR = 'https://raw.githubusercontent.com/HOT-Ecosystem/TermCI-model/main/' +GITHUB_DIR = "https://raw.githubusercontent.com/HOT-Ecosystem/TermCI-model/main/" GITHUB_INPUT_DIR = GITHUB_DIR + Path(os.path.relpath(INPUT_DIR, os.path.dirname(TESTING_DIR))).as_posix() -GITHUB_LD10_CONTEXT = GITHUB_DIR + Path(os.path.relpath(LD_10_DIR, os.path.dirname(TESTING_DIR))).as_posix() + '/' -GITHUB_LD11_CONTEXT = GITHUB_DIR + Path(os.path.relpath(LD_11_DIR, os.path.dirname(TESTING_DIR))).as_posix() + '/' +GITHUB_LD10_CONTEXT = GITHUB_DIR + Path(os.path.relpath(LD_10_DIR, os.path.dirname(TESTING_DIR))).as_posix() + "/" +GITHUB_LD11_CONTEXT = GITHUB_DIR + Path(os.path.relpath(LD_11_DIR, os.path.dirname(TESTING_DIR))).as_posix() + "/" SCT = Namespace("http://snomed.info/id/") OBO = Namespace("http://purl.obolibrary.org/obo/") @@ -26,10 +26,9 @@ SHACL = Namespace("http://www.w3.org/ns/shacl#") CONTEXT_SVR = f"http://localhost:{HTTP_TEST_PORT}/" -CONTEXT_SSL_SVR = f'https://localhost:{HTTPS_TEST_PORT}/' - -LD_10_SVR = CONTEXT_SVR + 'jsonld_10/' -LD_11_SVR = CONTEXT_SVR + 'jsonld_11/' -LD_10_SSL_SVR = CONTEXT_SSL_SVR + 'jsonld_10/' -LD_11_SSL_SVR = CONTEXT_SSL_SVR + 'jsonld_11/' +CONTEXT_SSL_SVR = f"https://localhost:{HTTPS_TEST_PORT}/" +LD_10_SVR = CONTEXT_SVR + "jsonld_10/" +LD_11_SVR = CONTEXT_SVR + "jsonld_11/" +LD_10_SSL_SVR = CONTEXT_SSL_SVR + "jsonld_10/" +LD_11_SSL_SVR = CONTEXT_SSL_SVR + "jsonld_11/" diff --git a/tests/test_loaders_dumpers/loaderdumpertestcase.py b/tests/test_loaders_dumpers/loaderdumpertestcase.py index e545a8cd..966afb30 100644 --- a/tests/test_loaders_dumpers/loaderdumpertestcase.py +++ b/tests/test_loaders_dumpers/loaderdumpertestcase.py @@ -3,20 +3,19 @@ from urllib.parse import urlparse from hbreader import FileInfo, hbread +from pydantic import BaseModel import tests.environment as test_base from linkml_runtime.dumpers import yaml_dumper from linkml_runtime.loaders.loader_root import Loader from linkml_runtime.utils.yamlutils import YAMLRoot -from pydantic import BaseModel from tests.support.test_environment import TestEnvironment, TestEnvironmentTestCase class LoaderDumperTestCase(TestEnvironmentTestCase): env = TestEnvironment(__file__) - def dump_test(self, filename: str, dumper: Callable[[str], None], comparator: Callable[[str], str] = None)\ - -> bool: + def dump_test(self, filename: str, dumper: Callable[[str], None], comparator: Callable[[str], str] = None) -> bool: """ Invoke the dumper passing it the output file name and then compare the result to an expected output :param filename: non-pathed file name to dump to and test @@ -25,7 +24,7 @@ def dump_test(self, filename: str, dumper: Callable[[str], None], comparator: C :returns: Success indicator """ actual_file = self.env.actual_path(filename) - expected_file = self.env.expected_path('dump', filename) + expected_file = self.env.expected_path("dump", filename) dumper(actual_file) @@ -41,7 +40,7 @@ def dumps_test(self, filename: str, dumper: Callable[[], str], comparator: Calla :param comparator: content comparator """ actual = dumper() - expected_file = self.env.expected_path('dumps', filename) + expected_file = self.env.expected_path("dumps", filename) return self.env.eval_single_file(expected_file, actual, comparator=comparator) @@ -54,8 +53,8 @@ def loader_test(self, filename: str, model: Union[type[YAMLRoot], type[BaseModel :param loader: package that contains 'load' and 'loads' operations """ metadata = FileInfo() - name, typ = filename.rsplit('.', 1) - expected_yaml = self.env.expected_path('load', name + '_' + typ + ".yaml") + name, typ = filename.rsplit(".", 1) + expected_yaml = self.env.expected_path("load", name + "_" + typ + ".yaml") if issubclass(model, YAMLRoot): python_obj: YAMLRoot = loader.load(filename, model, metadata=metadata, base_dir=self.env.indir) elif issubclass(model, BaseModel): @@ -65,14 +64,14 @@ def loader_test(self, filename: str, model: Union[type[YAMLRoot], type[BaseModel self.env.eval_single_file(expected_yaml, yaml_dumper.dumps(python_obj)) # Make sure metadata gets filled out properly - rel_path = os.path.abspath(os.path.join(test_base.env.cwd, '..')) + rel_path = os.path.abspath(os.path.join(test_base.env.cwd, "..")) self.assertEqual( - os.path.normpath('tests/test_loaders_dumpers/input'), - os.path.normpath(os.path.relpath(metadata.base_path, rel_path)) + os.path.normpath("tests/test_loaders_dumpers/input"), + os.path.normpath(os.path.relpath(metadata.base_path, rel_path)), ) self.assertEqual( - os.path.normpath(f'tests/test_loaders_dumpers/input/{filename}'), - os.path.normpath(os.path.relpath(metadata.source_file, rel_path)) + os.path.normpath(f"tests/test_loaders_dumpers/input/{filename}"), + os.path.normpath(os.path.relpath(metadata.source_file, rel_path)), ) fileinfo = FileInfo() @@ -95,9 +94,11 @@ def check_context_servers(possible_server: list[str]) -> Optional[str]: :return: Particular server to use """ + def is_listening(svr: str) -> bool: components = urlparse(svr) import socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: return s.connect_ex((components.hostname, components.port)) == 0 diff --git a/tests/test_loaders_dumpers/models/books_normalized.py b/tests/test_loaders_dumpers/models/books_normalized.py index 5ef2eb8d..02a1ad5f 100644 --- a/tests/test_loaders_dumpers/models/books_normalized.py +++ b/tests/test_loaders_dumpers/models/books_normalized.py @@ -6,29 +6,30 @@ # description: example # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str -from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from jsonasobj2 import as_dict from rdflib import URIRef + +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import empty_dict, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" # Namespaces -EXAMPLE = CurieNamespace('example', 'https://w3id.org/example') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') +EXAMPLE = CurieNamespace("example", "https://w3id.org/example") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") DEFAULT_ = EXAMPLE # Types + # Class references class CreativeWorkId(extended_str): pass @@ -188,7 +189,9 @@ class Shop(YAMLRoot): class_name: ClassVar[str] = "shop" class_model_uri: ClassVar[URIRef] = EXAMPLE.Shop - all_book_series: Optional[Union[dict[Union[str, BookSeriesId], Union[dict, BookSeries]], list[Union[dict, BookSeries]]]] = empty_dict() + all_book_series: Optional[ + Union[dict[Union[str, BookSeriesId], Union[dict, BookSeries]], list[Union[dict, BookSeries]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self._normalize_inlined_as_list(slot_name="all_book_series", slot_type=BookSeries, key_name="id", keyed=True) @@ -255,51 +258,131 @@ class GenreEnum(EnumDefinitionImpl): name="GenreEnum", ) + # Slots class slots: pass -slots.id = Slot(uri=EXAMPLE.id, name="id", curie=EXAMPLE.curie('id'), - model_uri=EXAMPLE.id, domain=None, range=URIRef) - -slots.book_category = Slot(uri=EXAMPLE.book_category, name="book_category", curie=EXAMPLE.curie('book_category'), - model_uri=EXAMPLE.book_category, domain=None, range=Optional[Union[str, list[str]]]) - -slots.name = Slot(uri=EXAMPLE.name, name="name", curie=EXAMPLE.curie('name'), - model_uri=EXAMPLE.name, domain=None, range=Optional[str]) - -slots.price = Slot(uri=EXAMPLE.price, name="price", curie=EXAMPLE.curie('price'), - model_uri=EXAMPLE.price, domain=None, range=Optional[float]) - -slots.inStock = Slot(uri=EXAMPLE.inStock, name="inStock", curie=EXAMPLE.curie('inStock'), - model_uri=EXAMPLE.inStock, domain=None, range=Optional[str]) - -slots.creator = Slot(uri=EXAMPLE.creator, name="creator", curie=EXAMPLE.curie('creator'), - model_uri=EXAMPLE.creator, domain=None, range=Optional[Union[dict, Author]]) - -slots.genres = Slot(uri=EXAMPLE.genres, name="genres", curie=EXAMPLE.curie('genres'), - model_uri=EXAMPLE.genres, domain=None, range=Optional[Union[Union[str, "GenreEnum"], list[Union[str, "GenreEnum"]]]]) - -slots.from_country = Slot(uri=EXAMPLE.from_country, name="from_country", curie=EXAMPLE.curie('from_country'), - model_uri=EXAMPLE.from_country, domain=None, range=Optional[Union[str, CountryName]]) - -slots.books = Slot(uri=EXAMPLE.books, name="books", curie=EXAMPLE.curie('books'), - model_uri=EXAMPLE.books, domain=None, range=Optional[Union[dict[Union[str, BookId], Union[dict, Book]], list[Union[dict, Book]]]]) - -slots.all_book_series = Slot(uri=EXAMPLE.all_book_series, name="all_book_series", curie=EXAMPLE.curie('all_book_series'), - model_uri=EXAMPLE.all_book_series, domain=None, range=Optional[Union[dict[Union[str, BookSeriesId], Union[dict, BookSeries]], list[Union[dict, BookSeries]]]]) - -slots.summary = Slot(uri=EXAMPLE.summary, name="summary", curie=EXAMPLE.curie('summary'), - model_uri=EXAMPLE.summary, domain=None, range=Optional[str]) - -slots.reviews = Slot(uri=EXAMPLE.reviews, name="reviews", curie=EXAMPLE.curie('reviews'), - model_uri=EXAMPLE.reviews, domain=None, range=Optional[Union[Union[dict, Review], list[Union[dict, Review]]]]) - -slots.rating = Slot(uri=EXAMPLE.rating, name="rating", curie=EXAMPLE.curie('rating'), - model_uri=EXAMPLE.rating, domain=None, range=Optional[int]) - -slots.review_text = Slot(uri=EXAMPLE.review_text, name="review_text", curie=EXAMPLE.curie('review_text'), - model_uri=EXAMPLE.review_text, domain=None, range=Optional[str]) -slots.country_name = Slot(uri=EXAMPLE.name, name="country_name", curie=EXAMPLE.curie('name'), - model_uri=EXAMPLE.country_name, domain=Country, range=Union[str, CountryName]) +slots.id = Slot(uri=EXAMPLE.id, name="id", curie=EXAMPLE.curie("id"), model_uri=EXAMPLE.id, domain=None, range=URIRef) + +slots.book_category = Slot( + uri=EXAMPLE.book_category, + name="book_category", + curie=EXAMPLE.curie("book_category"), + model_uri=EXAMPLE.book_category, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.name = Slot( + uri=EXAMPLE.name, name="name", curie=EXAMPLE.curie("name"), model_uri=EXAMPLE.name, domain=None, range=Optional[str] +) + +slots.price = Slot( + uri=EXAMPLE.price, + name="price", + curie=EXAMPLE.curie("price"), + model_uri=EXAMPLE.price, + domain=None, + range=Optional[float], +) + +slots.inStock = Slot( + uri=EXAMPLE.inStock, + name="inStock", + curie=EXAMPLE.curie("inStock"), + model_uri=EXAMPLE.inStock, + domain=None, + range=Optional[str], +) + +slots.creator = Slot( + uri=EXAMPLE.creator, + name="creator", + curie=EXAMPLE.curie("creator"), + model_uri=EXAMPLE.creator, + domain=None, + range=Optional[Union[dict, Author]], +) + +slots.genres = Slot( + uri=EXAMPLE.genres, + name="genres", + curie=EXAMPLE.curie("genres"), + model_uri=EXAMPLE.genres, + domain=None, + range=Optional[Union[Union[str, "GenreEnum"], list[Union[str, "GenreEnum"]]]], +) + +slots.from_country = Slot( + uri=EXAMPLE.from_country, + name="from_country", + curie=EXAMPLE.curie("from_country"), + model_uri=EXAMPLE.from_country, + domain=None, + range=Optional[Union[str, CountryName]], +) + +slots.books = Slot( + uri=EXAMPLE.books, + name="books", + curie=EXAMPLE.curie("books"), + model_uri=EXAMPLE.books, + domain=None, + range=Optional[Union[dict[Union[str, BookId], Union[dict, Book]], list[Union[dict, Book]]]], +) + +slots.all_book_series = Slot( + uri=EXAMPLE.all_book_series, + name="all_book_series", + curie=EXAMPLE.curie("all_book_series"), + model_uri=EXAMPLE.all_book_series, + domain=None, + range=Optional[Union[dict[Union[str, BookSeriesId], Union[dict, BookSeries]], list[Union[dict, BookSeries]]]], +) + +slots.summary = Slot( + uri=EXAMPLE.summary, + name="summary", + curie=EXAMPLE.curie("summary"), + model_uri=EXAMPLE.summary, + domain=None, + range=Optional[str], +) + +slots.reviews = Slot( + uri=EXAMPLE.reviews, + name="reviews", + curie=EXAMPLE.curie("reviews"), + model_uri=EXAMPLE.reviews, + domain=None, + range=Optional[Union[Union[dict, Review], list[Union[dict, Review]]]], +) + +slots.rating = Slot( + uri=EXAMPLE.rating, + name="rating", + curie=EXAMPLE.curie("rating"), + model_uri=EXAMPLE.rating, + domain=None, + range=Optional[int], +) + +slots.review_text = Slot( + uri=EXAMPLE.review_text, + name="review_text", + curie=EXAMPLE.curie("review_text"), + model_uri=EXAMPLE.review_text, + domain=None, + range=Optional[str], +) + +slots.country_name = Slot( + uri=EXAMPLE.name, + name="country_name", + curie=EXAMPLE.curie("name"), + model_uri=EXAMPLE.country_name, + domain=Country, + range=Union[str, CountryName], +) diff --git a/tests/test_loaders_dumpers/models/books_normalized_pydantic.py b/tests/test_loaders_dumpers/models/books_normalized_pydantic.py index 2200fb7a..cf2bf996 100644 --- a/tests/test_loaders_dumpers/models/books_normalized_pydantic.py +++ b/tests/test_loaders_dumpers/models/books_normalized_pydantic.py @@ -1,48 +1,51 @@ from __future__ import annotations + from enum import Enum from typing import Optional -from pydantic import BaseModel as BaseModel, Field + +from pydantic import BaseModel as BaseModel +from pydantic import Field metamodel_version = "None" version = "None" + class WeakRefShimBaseModel(BaseModel): - __slots__ = '__weakref__' + __slots__ = "__weakref__" + class ConfiguredBaseModel(WeakRefShimBaseModel): __signature__ = { "validate_assignment": True, "validate_all": True, "underscore_attrs_are_private": True, - "extra": 'forbid', + "extra": "forbid", "arbitrary_types_allowed": True, - "use_enum_values": True + "use_enum_values": True, } class GenreEnum(str, Enum): - + scifi = "scifi" fantasy = "fantasy" western = "western" romance = "romance" modern = "modern" - - + class CreativeWork(ConfiguredBaseModel): - + id: Optional[str] = Field(None) name: Optional[str] = Field(None) genres: Optional[list[GenreEnum]] = Field(default_factory=list) creator: Optional[Author] = Field(None) summary: Optional[str] = Field(None) reviews: Optional[list[Review]] = Field(default_factory=list) - class Book(CreativeWork): - + price: Optional[float] = Field(None) inStock: Optional[str] = Field(None) id: Optional[str] = Field(None) @@ -51,11 +54,10 @@ class Book(CreativeWork): creator: Optional[Author] = Field(None) summary: Optional[str] = Field(None) reviews: Optional[list[Review]] = Field(default_factory=list) - class BookSeries(CreativeWork): - + books: Optional[list[Book]] = Field(default_factory=list) genres: Optional[list[GenreEnum]] = Field(default_factory=list) price: Optional[float] = Field(None) @@ -64,36 +66,30 @@ class BookSeries(CreativeWork): creator: Optional[Author] = Field(None) summary: Optional[str] = Field(None) reviews: Optional[list[Review]] = Field(default_factory=list) - class Author(ConfiguredBaseModel): - + name: Optional[str] = Field(None) genres: Optional[list[GenreEnum]] = Field(default_factory=list) from_country: Optional[str] = Field(None) - class Shop(ConfiguredBaseModel): - + all_book_series: Optional[list[BookSeries]] = Field(default_factory=list) - class Country(ConfiguredBaseModel): - + name: Optional[str] = Field(None) - class Review(ConfiguredBaseModel): - + creator: Optional[Author] = Field(None) rating: Optional[int] = Field(None) review_text: Optional[str] = Field(None) - - # Update forward refs @@ -105,4 +101,3 @@ class Review(ConfiguredBaseModel): Shop.update_forward_refs() Country.update_forward_refs() Review.update_forward_refs() - diff --git a/tests/test_loaders_dumpers/models/enum_model.py b/tests/test_loaders_dumpers/models/enum_model.py index 29268796..d351af20 100644 --- a/tests/test_loaders_dumpers/models/enum_model.py +++ b/tests/test_loaders_dumpers/models/enum_model.py @@ -6,22 +6,21 @@ # description: # license: -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.yamlutils import YAMLRoot -from linkml_runtime.utils.enumerations import EnumDefinitionImpl from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot metamodel_version = "1.7.0" # Namespaces -DEFAULT_ = CurieNamespace('', 'https://example.org/enum_test/') +DEFAULT_ = CurieNamespace("", "https://example.org/enum_test/") # Types @@ -29,7 +28,6 @@ # Class references - @dataclass class Organism(YAMLRoot): _inherited_slots: ClassVar[list[str]] = [] @@ -58,9 +56,17 @@ class StateEnum(EnumDefinitionImpl): name="StateEnum", ) + # Slots class slots: pass -slots.state = Slot(uri=DEFAULT_.state, name="state", curie=DEFAULT_.curie('state'), - model_uri=DEFAULT_.state, domain=None, range=Optional[Union[str, "StateEnum"]]) + +slots.state = Slot( + uri=DEFAULT_.state, + name="state", + curie=DEFAULT_.curie("state"), + model_uri=DEFAULT_.state, + domain=None, + range=Optional[Union[str, "StateEnum"]], +) diff --git a/tests/test_loaders_dumpers/models/kitchen_sink_pydantic.py b/tests/test_loaders_dumpers/models/kitchen_sink_pydantic.py index bc99155d..44a173b5 100644 --- a/tests/test_loaders_dumpers/models/kitchen_sink_pydantic.py +++ b/tests/test_loaders_dumpers/models/kitchen_sink_pydantic.py @@ -1,79 +1,78 @@ from __future__ import annotations + from datetime import date from enum import Enum from typing import Any, Optional -from pydantic import BaseModel as BaseModel, Field + +from pydantic import BaseModel as BaseModel +from pydantic import Field metamodel_version = "None" version = "None" + class WeakRefShimBaseModel(BaseModel): - __slots__ = '__weakref__' + __slots__ = "__weakref__" + class ConfiguredBaseModel(WeakRefShimBaseModel): __signature__ = { "validate_assignment": True, "validate_all": True, "underscore_attrs_are_private": True, - "extra": 'forbid', + "extra": "forbid", "arbitrary_types_allowed": True, - "use_enum_values": True + "use_enum_values": True, } class FamilialRelationshipType(str, Enum): - + SIBLING_OF = "SIBLING_OF" PARENT_OF = "PARENT_OF" CHILD_OF = "CHILD_OF" - - + class DiagnosisType(str, Enum): - + TODO = "TODO" - - + class EmploymentEventType(str, Enum): - + HIRE = "HIRE" FIRE = "FIRE" PROMOTION = "PROMOTION" TRANSFER = "TRANSFER" - - + class OtherCodes(str, Enum): - + a_b = "a b" - - + class LifeStatusEnum(str, Enum): - + LIVING = "LIVING" DEAD = "DEAD" UNKNOWN = "UNKNOWN" - - + class HasAliases(ConfiguredBaseModel): - + aliases: Optional[list[str]] = Field(default_factory=list) - class Friend(ConfiguredBaseModel): - + name: Optional[str] = Field(None) - class Person(HasAliases): """ A person, living or dead """ + id: Optional[str] = Field(None) name: Optional[str] = Field(None) has_employment_history: Optional[list[EmploymentEvent]] = Field(None) @@ -86,117 +85,106 @@ class Person(HasAliases): stomach_count: Optional[int] = Field(None) is_living: Optional[LifeStatusEnum] = Field(None) aliases: Optional[list[str]] = Field(default_factory=list) - class Organization(HasAliases): """ - An organization. + An organization. -This description -includes newlines + This description + includes newlines -## Markdown headers + ## Markdown headers - * and - * a - * list + * and + * a + * list """ + id: Optional[str] = Field(None) name: Optional[str] = Field(None) aliases: Optional[list[str]] = Field(default_factory=list) - class Place(HasAliases): - + id: Optional[str] = Field(None) name: Optional[str] = Field(None) aliases: Optional[list[str]] = Field(default_factory=list) - class Address(ConfiguredBaseModel): - + street: Optional[str] = Field(None) city: Optional[str] = Field(None) - class Concept(ConfiguredBaseModel): - + id: Optional[str] = Field(None) name: Optional[str] = Field(None) in_code_system: Optional[str] = Field(None) - class DiagnosisConcept(Concept): - + id: Optional[str] = Field(None) name: Optional[str] = Field(None) in_code_system: Optional[str] = Field(None) - class ProcedureConcept(Concept): - + id: Optional[str] = Field(None) name: Optional[str] = Field(None) in_code_system: Optional[str] = Field(None) - class Event(ConfiguredBaseModel): - + started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) is_current: Optional[bool] = Field(None) metadata: Optional[Any] = Field(None, description="""Example of a slot that has an unconstrained range""") - class Relationship(ConfiguredBaseModel): - + started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) related_to: Optional[str] = Field(None) type: Optional[str] = Field(None) - class FamilialRelationship(Relationship): - + started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) related_to: str = Field(...) type: FamilialRelationshipType = Field(...) - class BirthEvent(Event): - + in_location: Optional[str] = Field(None) started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) is_current: Optional[bool] = Field(None) metadata: Optional[Any] = Field(None, description="""Example of a slot that has an unconstrained range""") - class EmploymentEvent(Event): - + employed_at: Optional[str] = Field(None) type: Optional[EmploymentEventType] = Field(None) started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) is_current: Optional[bool] = Field(None) metadata: Optional[Any] = Field(None, description="""Example of a slot that has an unconstrained range""") - class MedicalEvent(Event): - + in_location: Optional[str] = Field(None) diagnosis: Optional[DiagnosisConcept] = Field(None) procedure: Optional[ProcedureConcept] = Field(None) @@ -204,91 +192,82 @@ class MedicalEvent(Event): ended_at_time: Optional[date] = Field(None) is_current: Optional[bool] = Field(None) metadata: Optional[Any] = Field(None, description="""Example of a slot that has an unconstrained range""") - class WithLocation(ConfiguredBaseModel): - + in_location: Optional[str] = Field(None) - class MarriageEvent(WithLocation, Event): - + married_to: Optional[str] = Field(None) in_location: Optional[str] = Field(None) started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) is_current: Optional[bool] = Field(None) metadata: Optional[Any] = Field(None, description="""Example of a slot that has an unconstrained range""") - class Company(Organization): - + ceo: Optional[str] = Field(None) id: Optional[str] = Field(None) name: Optional[str] = Field(None) aliases: Optional[list[str]] = Field(default_factory=list) - class CodeSystem(ConfiguredBaseModel): - + id: Optional[str] = Field(None) name: Optional[str] = Field(None) - class Dataset(ConfiguredBaseModel): - + metadata: Optional[Any] = Field(None, description="""Example of a slot that has an unconstrained range""") persons: Optional[list[Person]] = Field(default_factory=list) companies: Optional[list[Company]] = Field(default_factory=list) activities: Optional[list[Activity]] = Field(default_factory=list) code_systems: Optional[dict[str, CodeSystem]] = Field(None) - class FakeClass(ConfiguredBaseModel): - + test_attribute: Optional[str] = Field(None) - class ClassWithSpaces(ConfiguredBaseModel): - + slot_with_space_1: Optional[str] = Field(None) - class SubclassTest(ClassWithSpaces): - + slot_with_space_2: Optional[ClassWithSpaces] = Field(None) slot_with_space_1: Optional[str] = Field(None) - class SubSubClass2(SubclassTest): - + slot_with_space_2: Optional[ClassWithSpaces] = Field(None) slot_with_space_1: Optional[str] = Field(None) - class TubSubClass1(SubclassTest): """ Same depth as Sub sub class 1 """ + slot_with_space_2: Optional[ClassWithSpaces] = Field(None) slot_with_space_1: Optional[str] = Field(None) - class Activity(ConfiguredBaseModel): """ a provence-generating activity """ + id: Optional[str] = Field(None) started_at_time: Optional[date] = Field(None) ended_at_time: Optional[date] = Field(None) @@ -296,18 +275,16 @@ class Activity(ConfiguredBaseModel): was_associated_with: Optional[str] = Field(None) used: Optional[str] = Field(None) description: Optional[str] = Field(None) - class Agent(ConfiguredBaseModel): """ a provence-generating agent """ + id: Optional[str] = Field(None) acted_on_behalf_of: Optional[str] = Field(None) was_informed_by: Optional[str] = Field(None) - - # Update forward refs @@ -339,4 +316,3 @@ class Agent(ConfiguredBaseModel): TubSubClass1.update_forward_refs() Activity.update_forward_refs() Agent.update_forward_refs() - diff --git a/tests/test_loaders_dumpers/models/node_object.py b/tests/test_loaders_dumpers/models/node_object.py index 8fbfe102..72c90b53 100644 --- a/tests/test_loaders_dumpers/models/node_object.py +++ b/tests/test_loaders_dumpers/models/node_object.py @@ -6,30 +6,31 @@ # description: Abstractions for working with RDF and RDFS triples # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str +from jsonasobj2 import as_dict from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.metamodelcore import empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" # Namespaces -EX = CurieNamespace('ex', 'https://w3id.org/example/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -SH = CurieNamespace('sh', 'http://www.w3.org/ns/shacl#') -SPARQLFUN = CurieNamespace('sparqlfun', 'https://w3id.org/sparqlfun/') +EX = CurieNamespace("ex", "https://w3id.org/example/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +SH = CurieNamespace("sh", "http://www.w3.org/ns/shacl#") +SPARQLFUN = CurieNamespace("sparqlfun", "https://w3id.org/sparqlfun/") DEFAULT_ = EX # Types + # Class references class NodeId(extended_str): pass @@ -44,6 +45,7 @@ class Triple(YAMLRoot): """ Represents an RDF triple """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = RDF.Statement @@ -120,23 +122,49 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.id = Slot(uri=EX.id, name="id", curie=EX.curie('id'), - model_uri=EX.id, domain=None, range=URIRef) - -slots.subject = Slot(uri=RDF.subject, name="subject", curie=RDF.curie('subject'), - model_uri=EX.subject, domain=None, range=Optional[Union[str, NodeId]]) - -slots.predicate = Slot(uri=RDF.predicate, name="predicate", curie=RDF.curie('predicate'), - model_uri=EX.predicate, domain=None, range=Optional[Union[str, NodeId]]) - -slots.object = Slot(uri=RDF.object, name="object", curie=RDF.curie('object'), - model_uri=EX.object, domain=None, range=Optional[str]) - -slots.graph = Slot(uri=EX.graph, name="graph", curie=EX.curie('graph'), - model_uri=EX.graph, domain=None, range=Optional[Union[str, NodeId]]) - -slots.statements = Slot(uri=SPARQLFUN.statements, name="statements", curie=SPARQLFUN.curie('statements'), - model_uri=EX.statements, domain=None, range=Optional[Union[Union[dict, Triple], list[Union[dict, Triple]]]]) -slots.type = Slot(uri=EX.type, name="type", curie=EX.curie('type'), - model_uri=EX.type, domain=None, range=Optional[Union[str, NodeId]]) +slots.id = Slot(uri=EX.id, name="id", curie=EX.curie("id"), model_uri=EX.id, domain=None, range=URIRef) + +slots.subject = Slot( + uri=RDF.subject, + name="subject", + curie=RDF.curie("subject"), + model_uri=EX.subject, + domain=None, + range=Optional[Union[str, NodeId]], +) + +slots.predicate = Slot( + uri=RDF.predicate, + name="predicate", + curie=RDF.curie("predicate"), + model_uri=EX.predicate, + domain=None, + range=Optional[Union[str, NodeId]], +) + +slots.object = Slot( + uri=RDF.object, name="object", curie=RDF.curie("object"), model_uri=EX.object, domain=None, range=Optional[str] +) + +slots.graph = Slot( + uri=EX.graph, + name="graph", + curie=EX.curie("graph"), + model_uri=EX.graph, + domain=None, + range=Optional[Union[str, NodeId]], +) + +slots.statements = Slot( + uri=SPARQLFUN.statements, + name="statements", + curie=SPARQLFUN.curie("statements"), + model_uri=EX.statements, + domain=None, + range=Optional[Union[Union[dict, Triple], list[Union[dict, Triple]]]], +) + +slots.type = Slot( + uri=EX.type, name="type", curie=EX.curie("type"), model_uri=EX.type, domain=None, range=Optional[Union[str, NodeId]] +) diff --git a/tests/test_loaders_dumpers/models/personinfo.py b/tests/test_loaders_dumpers/models/personinfo.py index 8b28bc49..167a8dd0 100644 --- a/tests/test_loaders_dumpers/models/personinfo.py +++ b/tests/test_loaders_dumpers/models/personinfo.py @@ -6,44 +6,44 @@ # description: Information about people, based on [schema.org](http://schema.org) # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses import re -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str -from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from jsonasobj2 import as_dict from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace + +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue from linkml_runtime.linkml_model.types import Decimal, Uri, Uriorcurie -from linkml_runtime.utils.metamodelcore import Bool, Decimal, XSDDate +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import Bool, XSDDate, empty_dict, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" version = None # Namespaces -GSSO = CurieNamespace('GSSO', 'http://purl.obolibrary.org/obo/GSSO_') -HP = CurieNamespace('HP', 'http://purl.obolibrary.org/obo/HP_') -BIZCODES = CurieNamespace('bizcodes', 'https://example.org/bizcodes/') -FAMREL = CurieNamespace('famrel', 'https://example.org/FamilialRelations#') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -PERSONINFO = CurieNamespace('personinfo', 'https://w3id.org/linkml/examples/personinfo/') -PROV = CurieNamespace('prov', 'http://www.w3.org/ns/prov#') -RDF = CurieNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') -RDFS = CurieNamespace('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +GSSO = CurieNamespace("GSSO", "http://purl.obolibrary.org/obo/GSSO_") +HP = CurieNamespace("HP", "http://purl.obolibrary.org/obo/HP_") +BIZCODES = CurieNamespace("bizcodes", "https://example.org/bizcodes/") +FAMREL = CurieNamespace("famrel", "https://example.org/FamilialRelations#") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +PERSONINFO = CurieNamespace("personinfo", "https://w3id.org/linkml/examples/personinfo/") +PROV = CurieNamespace("prov", "http://www.w3.org/ns/prov#") +RDF = CurieNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +RDFS = CurieNamespace("rdfs", "http://www.w3.org/2000/01/rdf-schema#") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = PERSONINFO # Types class CrossReference(Uriorcurie): - """ A string URI or CURIE representation of an external identifier, modeled as a Resource in RDF """ + """A string URI or CURIE representation of an external identifier, modeled as a Resource in RDF""" + type_class_uri = RDFS.Resource type_class_curie = "rdfs:Resource" type_name = "CrossReference" @@ -110,6 +110,7 @@ class NamedThing(YAMLRoot): """ A generic grouping for any identifiable entity """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PERSONINFO.NamedThing @@ -149,6 +150,7 @@ class Person(NamedThing): """ A person (alive, dead, undead, or fictional). """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SCHEMA.Person @@ -162,9 +164,15 @@ class Person(NamedThing): age_in_years: Optional[int] = None gender: Optional[Union[str, "GenderType"]] = None current_address: Optional[Union[dict, "Address"]] = None - has_employment_history: Optional[Union[Union[dict, "EmploymentEvent"], list[Union[dict, "EmploymentEvent"]]]] = empty_list() - has_familial_relationships: Optional[Union[Union[dict, "FamilialRelationship"], list[Union[dict, "FamilialRelationship"]]]] = empty_list() - has_interpersonal_relationships: Optional[Union[Union[dict, "InterPersonalRelationship"], list[Union[dict, "InterPersonalRelationship"]]]] = empty_list() + has_employment_history: Optional[Union[Union[dict, "EmploymentEvent"], list[Union[dict, "EmploymentEvent"]]]] = ( + empty_list() + ) + has_familial_relationships: Optional[ + Union[Union[dict, "FamilialRelationship"], list[Union[dict, "FamilialRelationship"]]] + ] = empty_list() + has_interpersonal_relationships: Optional[ + Union[Union[dict, "InterPersonalRelationship"], list[Union[dict, "InterPersonalRelationship"]]] + ] = empty_list() has_medical_history: Optional[Union[Union[dict, "MedicalEvent"], list[Union[dict, "MedicalEvent"]]]] = empty_list() aliases: Optional[Union[str, list[str]]] = empty_list() @@ -190,20 +198,36 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.current_address = Address(**as_dict(self.current_address)) if not isinstance(self.has_employment_history, list): - self.has_employment_history = [self.has_employment_history] if self.has_employment_history is not None else [] - self.has_employment_history = [v if isinstance(v, EmploymentEvent) else EmploymentEvent(**as_dict(v)) for v in self.has_employment_history] + self.has_employment_history = ( + [self.has_employment_history] if self.has_employment_history is not None else [] + ) + self.has_employment_history = [ + v if isinstance(v, EmploymentEvent) else EmploymentEvent(**as_dict(v)) for v in self.has_employment_history + ] if not isinstance(self.has_familial_relationships, list): - self.has_familial_relationships = [self.has_familial_relationships] if self.has_familial_relationships is not None else [] - self.has_familial_relationships = [v if isinstance(v, FamilialRelationship) else FamilialRelationship(**as_dict(v)) for v in self.has_familial_relationships] + self.has_familial_relationships = ( + [self.has_familial_relationships] if self.has_familial_relationships is not None else [] + ) + self.has_familial_relationships = [ + v if isinstance(v, FamilialRelationship) else FamilialRelationship(**as_dict(v)) + for v in self.has_familial_relationships + ] if not isinstance(self.has_interpersonal_relationships, list): - self.has_interpersonal_relationships = [self.has_interpersonal_relationships] if self.has_interpersonal_relationships is not None else [] - self.has_interpersonal_relationships = [v if isinstance(v, InterPersonalRelationship) else InterPersonalRelationship(**as_dict(v)) for v in self.has_interpersonal_relationships] + self.has_interpersonal_relationships = ( + [self.has_interpersonal_relationships] if self.has_interpersonal_relationships is not None else [] + ) + self.has_interpersonal_relationships = [ + v if isinstance(v, InterPersonalRelationship) else InterPersonalRelationship(**as_dict(v)) + for v in self.has_interpersonal_relationships + ] if not isinstance(self.has_medical_history, list): self.has_medical_history = [self.has_medical_history] if self.has_medical_history is not None else [] - self.has_medical_history = [v if isinstance(v, MedicalEvent) else MedicalEvent(**as_dict(v)) for v in self.has_medical_history] + self.has_medical_history = [ + v if isinstance(v, MedicalEvent) else MedicalEvent(**as_dict(v)) for v in self.has_medical_history + ] if not isinstance(self.aliases, list): self.aliases = [self.aliases] if self.aliases is not None else [] @@ -217,6 +241,7 @@ class HasAliases(YAMLRoot): """ A mixin applied to any class that can have aliases/alternateNames """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PERSONINFO.HasAliases @@ -239,6 +264,7 @@ class Organization(NamedThing): """ An organization such as a company or university """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SCHEMA.Organization @@ -671,7 +697,9 @@ class Container(YAMLRoot): class_model_uri: ClassVar[URIRef] = PERSONINFO.Container persons: Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]] = empty_dict() - organizations: Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]] = empty_dict() + organizations: Optional[ + Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self._normalize_inlined_as_list(slot_name="persons", slot_type=Person, key_name="id", keyed=True) @@ -684,28 +712,25 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): # Enumerations class FamilialRelationshipType(EnumDefinitionImpl): - SIBLING_OF = PermissibleValue(text="SIBLING_OF", - meaning=FAMREL["01"]) - PARENT_OF = PermissibleValue(text="PARENT_OF", - meaning=FAMREL["02"]) - CHILD_OF = PermissibleValue(text="CHILD_OF", - meaning=FAMREL["01"]) + SIBLING_OF = PermissibleValue(text="SIBLING_OF", meaning=FAMREL["01"]) + PARENT_OF = PermissibleValue(text="PARENT_OF", meaning=FAMREL["02"]) + CHILD_OF = PermissibleValue(text="CHILD_OF", meaning=FAMREL["01"]) _defn = EnumDefinition( name="FamilialRelationshipType", ) + class NonFamilialRelationshipType(EnumDefinitionImpl): - COWORKER_OF = PermissibleValue(text="COWORKER_OF", - meaning=FAMREL["70"]) - ROOMMATE_OF = PermissibleValue(text="ROOMMATE_OF", - meaning=FAMREL["70"]) + COWORKER_OF = PermissibleValue(text="COWORKER_OF", meaning=FAMREL["70"]) + ROOMMATE_OF = PermissibleValue(text="ROOMMATE_OF", meaning=FAMREL["70"]) _defn = EnumDefinition( name="NonFamilialRelationshipType", ) + class GenderType(EnumDefinitionImpl): _defn = EnumDefinition( @@ -714,24 +739,13 @@ class GenderType(EnumDefinitionImpl): @classmethod def _addvals(cls): - setattr(cls, "nonbinary man", - PermissibleValue(text="nonbinary man", - meaning=GSSO["009254"]) ) - setattr(cls, "nonbinary woman", - PermissibleValue(text="nonbinary woman", - meaning=GSSO["009253"]) ) - setattr(cls, "transgender woman", - PermissibleValue(text="transgender woman", - meaning=GSSO["000384"]) ) - setattr(cls, "transgender man", - PermissibleValue(text="transgender man", - meaning=GSSO["000372"]) ) - setattr(cls, "cisgender man", - PermissibleValue(text="cisgender man", - meaning=GSSO["000371"]) ) - setattr(cls, "cisgender woman", - PermissibleValue(text="cisgender woman", - meaning=GSSO["000385"]) ) + setattr(cls, "nonbinary man", PermissibleValue(text="nonbinary man", meaning=GSSO["009254"])) + setattr(cls, "nonbinary woman", PermissibleValue(text="nonbinary woman", meaning=GSSO["009253"])) + setattr(cls, "transgender woman", PermissibleValue(text="transgender woman", meaning=GSSO["000384"])) + setattr(cls, "transgender man", PermissibleValue(text="transgender man", meaning=GSSO["000372"])) + setattr(cls, "cisgender man", PermissibleValue(text="cisgender man", meaning=GSSO["000371"])) + setattr(cls, "cisgender woman", PermissibleValue(text="cisgender woman", meaning=GSSO["000385"])) + class DiagnosisType(EnumDefinitionImpl): @@ -741,11 +755,11 @@ class DiagnosisType(EnumDefinitionImpl): name="DiagnosisType", ) + class OrganizationType(EnumDefinitionImpl): offshore = PermissibleValue(text="offshore") - charity = PermissibleValue(text="charity", - meaning=BIZCODES["001"]) + charity = PermissibleValue(text="charity", meaning=BIZCODES["001"]) _defn = EnumDefinition( name="OrganizationType", @@ -753,157 +767,437 @@ class OrganizationType(EnumDefinitionImpl): @classmethod def _addvals(cls): - setattr(cls, "non profit", - PermissibleValue(text="non profit") ) - setattr(cls, "for profit", - PermissibleValue(text="for profit") ) - setattr(cls, "shell company", - PermissibleValue(text="shell company") ) - setattr(cls, "loose organization", - PermissibleValue(text="loose organization") ) + setattr(cls, "non profit", PermissibleValue(text="non profit")) + setattr(cls, "for profit", PermissibleValue(text="for profit")) + setattr(cls, "shell company", PermissibleValue(text="shell company")) + setattr(cls, "loose organization", PermissibleValue(text="loose organization")) + # Slots class slots: pass -slots.id = Slot(uri=SCHEMA.identifier, name="id", curie=SCHEMA.curie('identifier'), - model_uri=PERSONINFO.id, domain=None, range=URIRef) - -slots.name = Slot(uri=SCHEMA.name, name="name", curie=SCHEMA.curie('name'), - model_uri=PERSONINFO.name, domain=None, range=Optional[str]) - -slots.description = Slot(uri=SCHEMA.description, name="description", curie=SCHEMA.curie('description'), - model_uri=PERSONINFO.description, domain=None, range=Optional[str]) - -slots.image = Slot(uri=SCHEMA.image, name="image", curie=SCHEMA.curie('image'), - model_uri=PERSONINFO.image, domain=None, range=Optional[str]) - -slots.gender = Slot(uri=SCHEMA.gender, name="gender", curie=SCHEMA.curie('gender'), - model_uri=PERSONINFO.gender, domain=None, range=Optional[Union[str, "GenderType"]]) - -slots.primary_email = Slot(uri=SCHEMA.email, name="primary_email", curie=SCHEMA.curie('email'), - model_uri=PERSONINFO.primary_email, domain=None, range=Optional[str]) - -slots.birth_date = Slot(uri=SCHEMA.birthDate, name="birth_date", curie=SCHEMA.curie('birthDate'), - model_uri=PERSONINFO.birth_date, domain=None, range=Optional[str]) - -slots.employed_at = Slot(uri=PERSONINFO.employed_at, name="employed_at", curie=PERSONINFO.curie('employed_at'), - model_uri=PERSONINFO.employed_at, domain=None, range=Optional[Union[str, OrganizationId]]) - -slots.is_current = Slot(uri=PERSONINFO.is_current, name="is_current", curie=PERSONINFO.curie('is_current'), - model_uri=PERSONINFO.is_current, domain=None, range=Optional[Union[bool, Bool]]) - -slots.has_employment_history = Slot(uri=PERSONINFO.has_employment_history, name="has_employment_history", curie=PERSONINFO.curie('has_employment_history'), - model_uri=PERSONINFO.has_employment_history, domain=None, range=Optional[Union[Union[dict, EmploymentEvent], list[Union[dict, EmploymentEvent]]]]) - -slots.has_medical_history = Slot(uri=PERSONINFO.has_medical_history, name="has_medical_history", curie=PERSONINFO.curie('has_medical_history'), - model_uri=PERSONINFO.has_medical_history, domain=None, range=Optional[Union[Union[dict, MedicalEvent], list[Union[dict, MedicalEvent]]]]) - -slots.has_familial_relationships = Slot(uri=PERSONINFO.has_familial_relationships, name="has_familial_relationships", curie=PERSONINFO.curie('has_familial_relationships'), - model_uri=PERSONINFO.has_familial_relationships, domain=None, range=Optional[Union[Union[dict, FamilialRelationship], list[Union[dict, FamilialRelationship]]]]) - -slots.has_interpersonal_relationships = Slot(uri=PERSONINFO.has_interpersonal_relationships, name="has_interpersonal_relationships", curie=PERSONINFO.curie('has_interpersonal_relationships'), - model_uri=PERSONINFO.has_interpersonal_relationships, domain=None, range=Optional[Union[Union[dict, InterPersonalRelationship], list[Union[dict, InterPersonalRelationship]]]]) - -slots.in_location = Slot(uri=PERSONINFO.in_location, name="in location", curie=PERSONINFO.curie('in_location'), - model_uri=PERSONINFO.in_location, domain=None, range=Optional[Union[str, PlaceId]]) - -slots.current_address = Slot(uri=PERSONINFO.current_address, name="current_address", curie=PERSONINFO.curie('current_address'), - model_uri=PERSONINFO.current_address, domain=None, range=Optional[Union[dict, Address]]) - -slots.age_in_years = Slot(uri=PERSONINFO.age_in_years, name="age_in_years", curie=PERSONINFO.curie('age_in_years'), - model_uri=PERSONINFO.age_in_years, domain=None, range=Optional[int]) - -slots.score = Slot(uri=PERSONINFO.score, name="score", curie=PERSONINFO.curie('score'), - model_uri=PERSONINFO.score, domain=None, range=Optional[Decimal]) - -slots.related_to = Slot(uri=PERSONINFO.related_to, name="related_to", curie=PERSONINFO.curie('related_to'), - model_uri=PERSONINFO.related_to, domain=None, range=Optional[Union[str, NamedThingId]]) - -slots.depicted_by = Slot(uri=PERSONINFO.depicted_by, name="depicted_by", curie=PERSONINFO.curie('depicted_by'), - model_uri=PERSONINFO.depicted_by, domain=None, range=Optional[Union[str, ImageURL]]) - -slots.type = Slot(uri=PERSONINFO.type, name="type", curie=PERSONINFO.curie('type'), - model_uri=PERSONINFO.type, domain=None, range=Optional[str]) - -slots.subtype = Slot(uri=PERSONINFO.subtype, name="subtype", curie=PERSONINFO.curie('subtype'), - model_uri=PERSONINFO.subtype, domain=None, range=Optional[Union[str, ConceptId]]) - -slots.street = Slot(uri=PERSONINFO.street, name="street", curie=PERSONINFO.curie('street'), - model_uri=PERSONINFO.street, domain=None, range=Optional[str]) - -slots.city = Slot(uri=PERSONINFO.city, name="city", curie=PERSONINFO.curie('city'), - model_uri=PERSONINFO.city, domain=None, range=Optional[str]) - -slots.mission_statement = Slot(uri=PERSONINFO.mission_statement, name="mission_statement", curie=PERSONINFO.curie('mission_statement'), - model_uri=PERSONINFO.mission_statement, domain=None, range=Optional[str]) - -slots.founding_date = Slot(uri=PERSONINFO.founding_date, name="founding_date", curie=PERSONINFO.curie('founding_date'), - model_uri=PERSONINFO.founding_date, domain=None, range=Optional[str]) - -slots.founding_location = Slot(uri=PERSONINFO.founding_location, name="founding_location", curie=PERSONINFO.curie('founding_location'), - model_uri=PERSONINFO.founding_location, domain=None, range=Optional[Union[str, PlaceId]]) - -slots.postal_code = Slot(uri=PERSONINFO.postal_code, name="postal_code", curie=PERSONINFO.curie('postal_code'), - model_uri=PERSONINFO.postal_code, domain=None, range=Optional[str]) - -slots.started_at_time = Slot(uri=PROV.startedAtTime, name="started_at_time", curie=PROV.curie('startedAtTime'), - model_uri=PERSONINFO.started_at_time, domain=None, range=Optional[Union[str, XSDDate]]) - -slots.duration = Slot(uri=PERSONINFO.duration, name="duration", curie=PERSONINFO.curie('duration'), - model_uri=PERSONINFO.duration, domain=None, range=Optional[float]) - -slots.diagnosis = Slot(uri=PERSONINFO.diagnosis, name="diagnosis", curie=PERSONINFO.curie('diagnosis'), - model_uri=PERSONINFO.diagnosis, domain=None, range=Optional[Union[dict, DiagnosisConcept]]) - -slots.procedure = Slot(uri=PERSONINFO.procedure, name="procedure", curie=PERSONINFO.curie('procedure'), - model_uri=PERSONINFO.procedure, domain=None, range=Optional[Union[dict, ProcedureConcept]]) - -slots.ended_at_time = Slot(uri=PROV.endedAtTime, name="ended_at_time", curie=PROV.curie('endedAtTime'), - model_uri=PERSONINFO.ended_at_time, domain=None, range=Optional[Union[str, XSDDate]]) - -slots.categories = Slot(uri=PERSONINFO.categories, name="categories", curie=PERSONINFO.curie('categories'), - model_uri=PERSONINFO.categories, domain=None, range=Optional[Union[str, list[str]]]) - -slots.salary = Slot(uri=PERSONINFO.salary, name="salary", curie=PERSONINFO.curie('salary'), - model_uri=PERSONINFO.salary, domain=None, range=Optional[Union[Decimal, SalaryType]]) - -slots.min_salary = Slot(uri=PERSONINFO.min_salary, name="min_salary", curie=PERSONINFO.curie('min_salary'), - model_uri=PERSONINFO.min_salary, domain=None, range=Optional[Union[Decimal, SalaryType]]) - -slots.hasAliases__aliases = Slot(uri=PERSONINFO.aliases, name="hasAliases__aliases", curie=PERSONINFO.curie('aliases'), - model_uri=PERSONINFO.hasAliases__aliases, domain=None, range=Optional[Union[str, list[str]]]) - -slots.concept__code_system = Slot(uri=PERSONINFO.code_system, name="concept__code_system", curie=PERSONINFO.curie('code_system'), - model_uri=PERSONINFO.concept__code_system, domain=None, range=Optional[Union[str, CodeSystemId]]) - -slots.concept__mappings = Slot(uri=SKOS.exactMatch, name="concept__mappings", curie=SKOS.curie('exactMatch'), - model_uri=PERSONINFO.concept__mappings, domain=None, range=Optional[Union[Union[str, CrossReference], list[Union[str, CrossReference]]]]) - -slots.container__persons = Slot(uri=PERSONINFO.persons, name="container__persons", curie=PERSONINFO.curie('persons'), - model_uri=PERSONINFO.container__persons, domain=None, range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]]) - -slots.container__organizations = Slot(uri=PERSONINFO.organizations, name="container__organizations", curie=PERSONINFO.curie('organizations'), - model_uri=PERSONINFO.container__organizations, domain=None, range=Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]]) - -slots.related_to = Slot(uri=PERSONINFO.related_to, name="related to", curie=PERSONINFO.curie('related_to'), - model_uri=PERSONINFO.related_to, domain=None, range=Union[str, PersonId]) - -slots.Person_primary_email = Slot(uri=SCHEMA.email, name="Person_primary_email", curie=SCHEMA.curie('email'), - model_uri=PERSONINFO.Person_primary_email, domain=Person, range=Optional[str], - pattern=re.compile(r'^\S+@[\S+\.]+\S+')) - -slots.Organization_categories = Slot(uri=PERSONINFO.categories, name="Organization_categories", curie=PERSONINFO.curie('categories'), - model_uri=PERSONINFO.Organization_categories, domain=Organization, range=Optional[Union[Union[str, "OrganizationType"], list[Union[str, "OrganizationType"]]]]) - -slots.FamilialRelationship_type = Slot(uri=PERSONINFO.type, name="FamilialRelationship_type", curie=PERSONINFO.curie('type'), - model_uri=PERSONINFO.FamilialRelationship_type, domain=FamilialRelationship, range=Union[str, "FamilialRelationshipType"]) - -slots.FamilialRelationship_related_to = Slot(uri=PERSONINFO.related_to, name="FamilialRelationship_related to", curie=PERSONINFO.curie('related_to'), - model_uri=PERSONINFO.FamilialRelationship_related_to, domain=FamilialRelationship, range=Union[str, PersonId]) - -slots.InterPersonalRelationship_type = Slot(uri=PERSONINFO.type, name="InterPersonalRelationship_type", curie=PERSONINFO.curie('type'), - model_uri=PERSONINFO.InterPersonalRelationship_type, domain=InterPersonalRelationship, range=str) -slots.InterPersonalRelationship_related_to = Slot(uri=PERSONINFO.related_to, name="InterPersonalRelationship_related to", curie=PERSONINFO.curie('related_to'), - model_uri=PERSONINFO.InterPersonalRelationship_related_to, domain=InterPersonalRelationship, range=Union[str, PersonId]) +slots.id = Slot( + uri=SCHEMA.identifier, + name="id", + curie=SCHEMA.curie("identifier"), + model_uri=PERSONINFO.id, + domain=None, + range=URIRef, +) + +slots.name = Slot( + uri=SCHEMA.name, + name="name", + curie=SCHEMA.curie("name"), + model_uri=PERSONINFO.name, + domain=None, + range=Optional[str], +) + +slots.description = Slot( + uri=SCHEMA.description, + name="description", + curie=SCHEMA.curie("description"), + model_uri=PERSONINFO.description, + domain=None, + range=Optional[str], +) + +slots.image = Slot( + uri=SCHEMA.image, + name="image", + curie=SCHEMA.curie("image"), + model_uri=PERSONINFO.image, + domain=None, + range=Optional[str], +) + +slots.gender = Slot( + uri=SCHEMA.gender, + name="gender", + curie=SCHEMA.curie("gender"), + model_uri=PERSONINFO.gender, + domain=None, + range=Optional[Union[str, "GenderType"]], +) + +slots.primary_email = Slot( + uri=SCHEMA.email, + name="primary_email", + curie=SCHEMA.curie("email"), + model_uri=PERSONINFO.primary_email, + domain=None, + range=Optional[str], +) + +slots.birth_date = Slot( + uri=SCHEMA.birthDate, + name="birth_date", + curie=SCHEMA.curie("birthDate"), + model_uri=PERSONINFO.birth_date, + domain=None, + range=Optional[str], +) + +slots.employed_at = Slot( + uri=PERSONINFO.employed_at, + name="employed_at", + curie=PERSONINFO.curie("employed_at"), + model_uri=PERSONINFO.employed_at, + domain=None, + range=Optional[Union[str, OrganizationId]], +) + +slots.is_current = Slot( + uri=PERSONINFO.is_current, + name="is_current", + curie=PERSONINFO.curie("is_current"), + model_uri=PERSONINFO.is_current, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.has_employment_history = Slot( + uri=PERSONINFO.has_employment_history, + name="has_employment_history", + curie=PERSONINFO.curie("has_employment_history"), + model_uri=PERSONINFO.has_employment_history, + domain=None, + range=Optional[Union[Union[dict, EmploymentEvent], list[Union[dict, EmploymentEvent]]]], +) + +slots.has_medical_history = Slot( + uri=PERSONINFO.has_medical_history, + name="has_medical_history", + curie=PERSONINFO.curie("has_medical_history"), + model_uri=PERSONINFO.has_medical_history, + domain=None, + range=Optional[Union[Union[dict, MedicalEvent], list[Union[dict, MedicalEvent]]]], +) + +slots.has_familial_relationships = Slot( + uri=PERSONINFO.has_familial_relationships, + name="has_familial_relationships", + curie=PERSONINFO.curie("has_familial_relationships"), + model_uri=PERSONINFO.has_familial_relationships, + domain=None, + range=Optional[Union[Union[dict, FamilialRelationship], list[Union[dict, FamilialRelationship]]]], +) + +slots.has_interpersonal_relationships = Slot( + uri=PERSONINFO.has_interpersonal_relationships, + name="has_interpersonal_relationships", + curie=PERSONINFO.curie("has_interpersonal_relationships"), + model_uri=PERSONINFO.has_interpersonal_relationships, + domain=None, + range=Optional[Union[Union[dict, InterPersonalRelationship], list[Union[dict, InterPersonalRelationship]]]], +) + +slots.in_location = Slot( + uri=PERSONINFO.in_location, + name="in location", + curie=PERSONINFO.curie("in_location"), + model_uri=PERSONINFO.in_location, + domain=None, + range=Optional[Union[str, PlaceId]], +) + +slots.current_address = Slot( + uri=PERSONINFO.current_address, + name="current_address", + curie=PERSONINFO.curie("current_address"), + model_uri=PERSONINFO.current_address, + domain=None, + range=Optional[Union[dict, Address]], +) + +slots.age_in_years = Slot( + uri=PERSONINFO.age_in_years, + name="age_in_years", + curie=PERSONINFO.curie("age_in_years"), + model_uri=PERSONINFO.age_in_years, + domain=None, + range=Optional[int], +) + +slots.score = Slot( + uri=PERSONINFO.score, + name="score", + curie=PERSONINFO.curie("score"), + model_uri=PERSONINFO.score, + domain=None, + range=Optional[Decimal], +) + +slots.related_to = Slot( + uri=PERSONINFO.related_to, + name="related_to", + curie=PERSONINFO.curie("related_to"), + model_uri=PERSONINFO.related_to, + domain=None, + range=Optional[Union[str, NamedThingId]], +) + +slots.depicted_by = Slot( + uri=PERSONINFO.depicted_by, + name="depicted_by", + curie=PERSONINFO.curie("depicted_by"), + model_uri=PERSONINFO.depicted_by, + domain=None, + range=Optional[Union[str, ImageURL]], +) + +slots.type = Slot( + uri=PERSONINFO.type, + name="type", + curie=PERSONINFO.curie("type"), + model_uri=PERSONINFO.type, + domain=None, + range=Optional[str], +) + +slots.subtype = Slot( + uri=PERSONINFO.subtype, + name="subtype", + curie=PERSONINFO.curie("subtype"), + model_uri=PERSONINFO.subtype, + domain=None, + range=Optional[Union[str, ConceptId]], +) + +slots.street = Slot( + uri=PERSONINFO.street, + name="street", + curie=PERSONINFO.curie("street"), + model_uri=PERSONINFO.street, + domain=None, + range=Optional[str], +) + +slots.city = Slot( + uri=PERSONINFO.city, + name="city", + curie=PERSONINFO.curie("city"), + model_uri=PERSONINFO.city, + domain=None, + range=Optional[str], +) + +slots.mission_statement = Slot( + uri=PERSONINFO.mission_statement, + name="mission_statement", + curie=PERSONINFO.curie("mission_statement"), + model_uri=PERSONINFO.mission_statement, + domain=None, + range=Optional[str], +) + +slots.founding_date = Slot( + uri=PERSONINFO.founding_date, + name="founding_date", + curie=PERSONINFO.curie("founding_date"), + model_uri=PERSONINFO.founding_date, + domain=None, + range=Optional[str], +) + +slots.founding_location = Slot( + uri=PERSONINFO.founding_location, + name="founding_location", + curie=PERSONINFO.curie("founding_location"), + model_uri=PERSONINFO.founding_location, + domain=None, + range=Optional[Union[str, PlaceId]], +) + +slots.postal_code = Slot( + uri=PERSONINFO.postal_code, + name="postal_code", + curie=PERSONINFO.curie("postal_code"), + model_uri=PERSONINFO.postal_code, + domain=None, + range=Optional[str], +) + +slots.started_at_time = Slot( + uri=PROV.startedAtTime, + name="started_at_time", + curie=PROV.curie("startedAtTime"), + model_uri=PERSONINFO.started_at_time, + domain=None, + range=Optional[Union[str, XSDDate]], +) + +slots.duration = Slot( + uri=PERSONINFO.duration, + name="duration", + curie=PERSONINFO.curie("duration"), + model_uri=PERSONINFO.duration, + domain=None, + range=Optional[float], +) + +slots.diagnosis = Slot( + uri=PERSONINFO.diagnosis, + name="diagnosis", + curie=PERSONINFO.curie("diagnosis"), + model_uri=PERSONINFO.diagnosis, + domain=None, + range=Optional[Union[dict, DiagnosisConcept]], +) + +slots.procedure = Slot( + uri=PERSONINFO.procedure, + name="procedure", + curie=PERSONINFO.curie("procedure"), + model_uri=PERSONINFO.procedure, + domain=None, + range=Optional[Union[dict, ProcedureConcept]], +) + +slots.ended_at_time = Slot( + uri=PROV.endedAtTime, + name="ended_at_time", + curie=PROV.curie("endedAtTime"), + model_uri=PERSONINFO.ended_at_time, + domain=None, + range=Optional[Union[str, XSDDate]], +) + +slots.categories = Slot( + uri=PERSONINFO.categories, + name="categories", + curie=PERSONINFO.curie("categories"), + model_uri=PERSONINFO.categories, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.salary = Slot( + uri=PERSONINFO.salary, + name="salary", + curie=PERSONINFO.curie("salary"), + model_uri=PERSONINFO.salary, + domain=None, + range=Optional[Union[Decimal, SalaryType]], +) + +slots.min_salary = Slot( + uri=PERSONINFO.min_salary, + name="min_salary", + curie=PERSONINFO.curie("min_salary"), + model_uri=PERSONINFO.min_salary, + domain=None, + range=Optional[Union[Decimal, SalaryType]], +) + +slots.hasAliases__aliases = Slot( + uri=PERSONINFO.aliases, + name="hasAliases__aliases", + curie=PERSONINFO.curie("aliases"), + model_uri=PERSONINFO.hasAliases__aliases, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.concept__code_system = Slot( + uri=PERSONINFO.code_system, + name="concept__code_system", + curie=PERSONINFO.curie("code_system"), + model_uri=PERSONINFO.concept__code_system, + domain=None, + range=Optional[Union[str, CodeSystemId]], +) + +slots.concept__mappings = Slot( + uri=SKOS.exactMatch, + name="concept__mappings", + curie=SKOS.curie("exactMatch"), + model_uri=PERSONINFO.concept__mappings, + domain=None, + range=Optional[Union[Union[str, CrossReference], list[Union[str, CrossReference]]]], +) + +slots.container__persons = Slot( + uri=PERSONINFO.persons, + name="container__persons", + curie=PERSONINFO.curie("persons"), + model_uri=PERSONINFO.container__persons, + domain=None, + range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]], +) + +slots.container__organizations = Slot( + uri=PERSONINFO.organizations, + name="container__organizations", + curie=PERSONINFO.curie("organizations"), + model_uri=PERSONINFO.container__organizations, + domain=None, + range=Optional[Union[dict[Union[str, OrganizationId], Union[dict, Organization]], list[Union[dict, Organization]]]], +) + +slots.related_to = Slot( + uri=PERSONINFO.related_to, + name="related to", + curie=PERSONINFO.curie("related_to"), + model_uri=PERSONINFO.related_to, + domain=None, + range=Union[str, PersonId], +) + +slots.Person_primary_email = Slot( + uri=SCHEMA.email, + name="Person_primary_email", + curie=SCHEMA.curie("email"), + model_uri=PERSONINFO.Person_primary_email, + domain=Person, + range=Optional[str], + pattern=re.compile(r"^\S+@[\S+\.]+\S+"), +) + +slots.Organization_categories = Slot( + uri=PERSONINFO.categories, + name="Organization_categories", + curie=PERSONINFO.curie("categories"), + model_uri=PERSONINFO.Organization_categories, + domain=Organization, + range=Optional[Union[Union[str, "OrganizationType"], list[Union[str, "OrganizationType"]]]], +) + +slots.FamilialRelationship_type = Slot( + uri=PERSONINFO.type, + name="FamilialRelationship_type", + curie=PERSONINFO.curie("type"), + model_uri=PERSONINFO.FamilialRelationship_type, + domain=FamilialRelationship, + range=Union[str, "FamilialRelationshipType"], +) + +slots.FamilialRelationship_related_to = Slot( + uri=PERSONINFO.related_to, + name="FamilialRelationship_related to", + curie=PERSONINFO.curie("related_to"), + model_uri=PERSONINFO.FamilialRelationship_related_to, + domain=FamilialRelationship, + range=Union[str, PersonId], +) + +slots.InterPersonalRelationship_type = Slot( + uri=PERSONINFO.type, + name="InterPersonalRelationship_type", + curie=PERSONINFO.curie("type"), + model_uri=PERSONINFO.InterPersonalRelationship_type, + domain=InterPersonalRelationship, + range=str, +) + +slots.InterPersonalRelationship_related_to = Slot( + uri=PERSONINFO.related_to, + name="InterPersonalRelationship_related to", + curie=PERSONINFO.curie("related_to"), + model_uri=PERSONINFO.InterPersonalRelationship_related_to, + domain=InterPersonalRelationship, + range=Union[str, PersonId], +) diff --git a/tests/test_loaders_dumpers/models/personinfo_test_issue_429.py b/tests/test_loaders_dumpers/models/personinfo_test_issue_429.py index 4ec14d1c..210b8951 100644 --- a/tests/test_loaders_dumpers/models/personinfo_test_issue_429.py +++ b/tests/test_loaders_dumpers/models/personinfo_test_issue_429.py @@ -6,29 +6,30 @@ # description: # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.metamodelcore import empty_dict +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" version = None # Namespaces -ORCID = CurieNamespace('ORCID', 'https://orcid.org/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -PERSONINFO = CurieNamespace('personinfo', 'https://w3id.org/linkml/examples/personinfo/') -SDO = CurieNamespace('sdo', 'http://schema.org/') +ORCID = CurieNamespace("ORCID", "https://orcid.org/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +PERSONINFO = CurieNamespace("personinfo", "https://w3id.org/linkml/examples/personinfo/") +SDO = CurieNamespace("sdo", "http://schema.org/") DEFAULT_ = PERSONINFO # Types + # Class references class PersonId(extended_str): pass @@ -90,17 +91,43 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): class slots: pass -slots.id = Slot(uri=PERSONINFO.id, name="id", curie=PERSONINFO.curie('id'), - model_uri=PERSONINFO.id, domain=None, range=URIRef) - -slots.full_name = Slot(uri=PERSONINFO.full_name, name="full_name", curie=PERSONINFO.curie('full_name'), - model_uri=PERSONINFO.full_name, domain=None, range=Optional[str]) - -slots.age = Slot(uri=PERSONINFO.age, name="age", curie=PERSONINFO.curie('age'), - model_uri=PERSONINFO.age, domain=None, range=Optional[str]) - -slots.phone = Slot(uri=PERSONINFO.phone, name="phone", curie=PERSONINFO.curie('phone'), - model_uri=PERSONINFO.phone, domain=None, range=Optional[str]) -slots.container__persons = Slot(uri=PERSONINFO.persons, name="container__persons", curie=PERSONINFO.curie('persons'), - model_uri=PERSONINFO.container__persons, domain=None, range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]]) +slots.id = Slot( + uri=PERSONINFO.id, name="id", curie=PERSONINFO.curie("id"), model_uri=PERSONINFO.id, domain=None, range=URIRef +) + +slots.full_name = Slot( + uri=PERSONINFO.full_name, + name="full_name", + curie=PERSONINFO.curie("full_name"), + model_uri=PERSONINFO.full_name, + domain=None, + range=Optional[str], +) + +slots.age = Slot( + uri=PERSONINFO.age, + name="age", + curie=PERSONINFO.curie("age"), + model_uri=PERSONINFO.age, + domain=None, + range=Optional[str], +) + +slots.phone = Slot( + uri=PERSONINFO.phone, + name="phone", + curie=PERSONINFO.curie("phone"), + model_uri=PERSONINFO.phone, + domain=None, + range=Optional[str], +) + +slots.container__persons = Slot( + uri=PERSONINFO.persons, + name="container__persons", + curie=PERSONINFO.curie("persons"), + model_uri=PERSONINFO.container__persons, + domain=None, + range=Optional[Union[dict[Union[str, PersonId], Union[dict, Person]], list[Union[dict, Person]]]], +) diff --git a/tests/test_loaders_dumpers/models/phenopackets.py b/tests/test_loaders_dumpers/models/phenopackets.py index 5ad33459..a5cc1c5a 100644 --- a/tests/test_loaders_dumpers/models/phenopackets.py +++ b/tests/test_loaders_dumpers/models/phenopackets.py @@ -6,55 +6,55 @@ # description: Automatic translation of phenopackets protobuf to LinkML. Status: EXPERIMENTAL. # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str -from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from jsonasobj2 import as_dict from rdflib import URIRef + +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import Bool +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import Bool, empty_dict, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" version = None # Namespaces -ARGO = CurieNamespace('ARGO', 'https://docs.icgc-argo.org/dictionary/') -GENO = CurieNamespace('GENO', 'http://purl.obolibrary.org/obo/GENO_') -HP = CurieNamespace('HP', 'http://purl.obolibrary.org/obo/HP_') -LOINC = CurieNamespace('LOINC', 'https://loinc.org/') -MONDO = CurieNamespace('MONDO', 'http://purl.obolibrary.org/obo/MONDO_') -NCIT = CurieNamespace('NCIT', 'http://purl.obolibrary.org/obo/NCIT_') -UBERON = CurieNamespace('UBERON', 'http://purl.obolibrary.org/obo/UBERON_') -UCUM = CurieNamespace('UCUM', 'http://unitsofmeasure.org/') -UO = CurieNamespace('UO', 'http://purl.obolibrary.org/obo/UO_') -ANY = CurieNamespace('any', 'https://w3id.org/linkml/phenopackets/any/') -ARGO = CurieNamespace('argo', 'https://docs.icgc-argo.org/dictionary/') -BASE = CurieNamespace('base', 'https://w3id.org/linkml/phenopackets/base/') -BIOSAMPLE = CurieNamespace('biosample', 'https://w3id.org/linkml/phenopackets/biosample/') -DISEASE = CurieNamespace('disease', 'https://w3id.org/linkml/phenopackets/disease/') -INDIVIDUAL = CurieNamespace('individual', 'https://w3id.org/linkml/phenopackets/individual/') -INTERPRETATION = CurieNamespace('interpretation', 'https://w3id.org/linkml/phenopackets/interpretation/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -MEASUREMENT = CurieNamespace('measurement', 'https://w3id.org/linkml/phenopackets/measurement/') -MEDICAL_ACTION = CurieNamespace('medical_action', 'https://w3id.org/linkml/phenopackets/medical_action/') -META_DATA = CurieNamespace('meta_data', 'https://w3id.org/linkml/phenopackets/meta_data/') -PEDIGREE = CurieNamespace('pedigree', 'https://w3id.org/linkml/phenopackets/pedigree/') -PHENOPACKETS = CurieNamespace('phenopackets', 'https://w3id.org/linkml/phenopackets/phenopackets/') -PHENOTYPIC_FEATURE = CurieNamespace('phenotypic_feature', 'https://w3id.org/linkml/phenopackets/phenotypic_feature/') -TIMESTAMP = CurieNamespace('timestamp', 'https://w3id.org/linkml/phenopackets/timestamp/') -VRS = CurieNamespace('vrs', 'https://w3id.org/linkml/phenopackets/vrs/') -VRSATILE = CurieNamespace('vrsatile', 'https://w3id.org/linkml/phenopackets/vrsatile/') +ARGO = CurieNamespace("ARGO", "https://docs.icgc-argo.org/dictionary/") +GENO = CurieNamespace("GENO", "http://purl.obolibrary.org/obo/GENO_") +HP = CurieNamespace("HP", "http://purl.obolibrary.org/obo/HP_") +LOINC = CurieNamespace("LOINC", "https://loinc.org/") +MONDO = CurieNamespace("MONDO", "http://purl.obolibrary.org/obo/MONDO_") +NCIT = CurieNamespace("NCIT", "http://purl.obolibrary.org/obo/NCIT_") +UBERON = CurieNamespace("UBERON", "http://purl.obolibrary.org/obo/UBERON_") +UCUM = CurieNamespace("UCUM", "http://unitsofmeasure.org/") +UO = CurieNamespace("UO", "http://purl.obolibrary.org/obo/UO_") +ANY = CurieNamespace("any", "https://w3id.org/linkml/phenopackets/any/") +ARGO = CurieNamespace("argo", "https://docs.icgc-argo.org/dictionary/") +BASE = CurieNamespace("base", "https://w3id.org/linkml/phenopackets/base/") +BIOSAMPLE = CurieNamespace("biosample", "https://w3id.org/linkml/phenopackets/biosample/") +DISEASE = CurieNamespace("disease", "https://w3id.org/linkml/phenopackets/disease/") +INDIVIDUAL = CurieNamespace("individual", "https://w3id.org/linkml/phenopackets/individual/") +INTERPRETATION = CurieNamespace("interpretation", "https://w3id.org/linkml/phenopackets/interpretation/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +MEASUREMENT = CurieNamespace("measurement", "https://w3id.org/linkml/phenopackets/measurement/") +MEDICAL_ACTION = CurieNamespace("medical_action", "https://w3id.org/linkml/phenopackets/medical_action/") +META_DATA = CurieNamespace("meta_data", "https://w3id.org/linkml/phenopackets/meta_data/") +PEDIGREE = CurieNamespace("pedigree", "https://w3id.org/linkml/phenopackets/pedigree/") +PHENOPACKETS = CurieNamespace("phenopackets", "https://w3id.org/linkml/phenopackets/phenopackets/") +PHENOTYPIC_FEATURE = CurieNamespace("phenotypic_feature", "https://w3id.org/linkml/phenopackets/phenotypic_feature/") +TIMESTAMP = CurieNamespace("timestamp", "https://w3id.org/linkml/phenopackets/timestamp/") +VRS = CurieNamespace("vrs", "https://w3id.org/linkml/phenopackets/vrs/") +VRSATILE = CurieNamespace("vrsatile", "https://w3id.org/linkml/phenopackets/vrsatile/") DEFAULT_ = PHENOPACKETS # Types + # Class references class OntologyClassId(extended_str): pass @@ -65,6 +65,7 @@ class Cohort(YAMLRoot): """ A group of individuals related in some phenotypic or genotypic aspect. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PHENOPACKETS.Cohort @@ -106,6 +107,7 @@ class Family(YAMLRoot): InterpretationRequestRD https://github.com/genomicsengland/GelReportModels/blob/master/schemas/IDLs/org.gel.models.report.avro/5.0.0/InterpretationRequestRD.avdl """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PHENOPACKETS.Family @@ -156,6 +158,7 @@ class Phenopacket(YAMLRoot): expected that the resources sharing the phenopackets will define and enforce their own semantics and level of requirements for included fields. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PHENOPACKETS.Phenopacket @@ -171,7 +174,9 @@ class Phenopacket(YAMLRoot): interpretations: Optional[Union[Union[dict, "Interpretation"], list[Union[dict, "Interpretation"]]]] = empty_list() measurements: Optional[Union[Union[dict, "Measurement"], list[Union[dict, "Measurement"]]]] = empty_list() medicalActions: Optional[Union[Union[dict, "MedicalAction"], list[Union[dict, "MedicalAction"]]]] = empty_list() - phenotypicFeatures: Optional[Union[Union[dict, "PhenotypicFeature"], list[Union[dict, "PhenotypicFeature"]]]] = empty_list() + phenotypicFeatures: Optional[Union[Union[dict, "PhenotypicFeature"], list[Union[dict, "PhenotypicFeature"]]]] = ( + empty_list() + ) subject: Optional[Union[dict, "Individual"]] = None def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): @@ -197,7 +202,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.interpretations, list): self.interpretations = [self.interpretations] if self.interpretations is not None else [] - self.interpretations = [v if isinstance(v, Interpretation) else Interpretation(**as_dict(v)) for v in self.interpretations] + self.interpretations = [ + v if isinstance(v, Interpretation) else Interpretation(**as_dict(v)) for v in self.interpretations + ] if not isinstance(self.measurements, list): self.measurements = [self.measurements] if self.measurements is not None else [] @@ -205,11 +212,15 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.medicalActions, list): self.medicalActions = [self.medicalActions] if self.medicalActions is not None else [] - self.medicalActions = [v if isinstance(v, MedicalAction) else MedicalAction(**as_dict(v)) for v in self.medicalActions] + self.medicalActions = [ + v if isinstance(v, MedicalAction) else MedicalAction(**as_dict(v)) for v in self.medicalActions + ] if not isinstance(self.phenotypicFeatures, list): self.phenotypicFeatures = [self.phenotypicFeatures] if self.phenotypicFeatures is not None else [] - self.phenotypicFeatures = [v if isinstance(v, PhenotypicFeature) else PhenotypicFeature(**as_dict(v)) for v in self.phenotypicFeatures] + self.phenotypicFeatures = [ + v if isinstance(v, PhenotypicFeature) else PhenotypicFeature(**as_dict(v)) for v in self.phenotypicFeatures + ] if self.subject is not None and not isinstance(self.subject, Individual): self.subject = Individual(**as_dict(self.subject)) @@ -223,6 +234,7 @@ class Age(YAMLRoot): See http://build.fhir.org/datatypes and http://build.fhir.org/condition-definitions.html#Condition.onset_x_ In FHIR this is represented as a UCUM measurement - http://unitsofmeasure.org/trac/ """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = BASE.Age @@ -275,6 +287,7 @@ class Evidence(YAMLRoot): """ FHIR mapping: Condition.evidence (https://www.hl7.org/fhir/condition-definitions.html#Condition.evidence) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = BASE.Evidence @@ -300,6 +313,7 @@ class ExternalReference(YAMLRoot): """ FHIR mapping: Reference (https://www.hl7.org/fhir/references.html) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = BASE.ExternalReference @@ -341,7 +355,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.fileAttributes is not None and not isinstance(self.fileAttributes, Dictionary): self.fileAttributes = Dictionary() - if self.individualToFileIdentifiers is not None and not isinstance(self.individualToFileIdentifiers, Dictionary): + if self.individualToFileIdentifiers is not None and not isinstance( + self.individualToFileIdentifiers, Dictionary + ): self.individualToFileIdentifiers = Dictionary() if self.uri is not None and not isinstance(self.uri, str): @@ -379,6 +395,7 @@ class OntologyClass(YAMLRoot): (http://www.hl7.org/fhir/datatypes.html#CodeableConcept) see also Coding (http://www.hl7.org/fhir/datatypes.html#Coding) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = BASE.OntologyClass @@ -410,6 +427,7 @@ class Procedure(YAMLRoot): "body_site":{"UBERON:0003403": "skin of forearm"}} - a punch biopsy of the skin from the forearm FHIR mapping: Procedure (https://www.hl7.org/fhir/procedure.html) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = BASE.Procedure @@ -504,6 +522,7 @@ class Biosample(YAMLRoot): genomic array as well as RNA-seq experiments) may refer to the same Biosample. FHIR mapping: Specimen (http://www.hl7.org/fhir/specimen.html). """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = BIOSAMPLE.Biosample @@ -513,7 +532,9 @@ class Biosample(YAMLRoot): derivedFromId: Optional[str] = None description: Optional[str] = None - diagnosticMarkers: Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]] = empty_dict() + diagnosticMarkers: Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ] = empty_dict() files: Optional[Union[Union[dict, File], list[Union[dict, File]]]] = empty_list() histologicalDiagnosis: Optional[Union[dict, OntologyClass]] = None id: Optional[str] = None @@ -521,8 +542,12 @@ class Biosample(YAMLRoot): materialSample: Optional[Union[dict, OntologyClass]] = None measurements: Optional[Union[Union[dict, "Measurement"], list[Union[dict, "Measurement"]]]] = empty_list() pathologicalStage: Optional[Union[dict, OntologyClass]] = None - pathologicalTnmFinding: Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]] = empty_dict() - phenotypicFeatures: Optional[Union[Union[dict, "PhenotypicFeature"], list[Union[dict, "PhenotypicFeature"]]]] = empty_list() + pathologicalTnmFinding: Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ] = empty_dict() + phenotypicFeatures: Optional[Union[Union[dict, "PhenotypicFeature"], list[Union[dict, "PhenotypicFeature"]]]] = ( + empty_list() + ) procedure: Optional[Union[dict, Procedure]] = None sampleProcessing: Optional[Union[dict, OntologyClass]] = None sampleStorage: Optional[Union[dict, OntologyClass]] = None @@ -540,7 +565,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.description is not None and not isinstance(self.description, str): self.description = str(self.description) - self._normalize_inlined_as_dict(slot_name="diagnosticMarkers", slot_type=OntologyClass, key_name="id", keyed=True) + self._normalize_inlined_as_dict( + slot_name="diagnosticMarkers", slot_type=OntologyClass, key_name="id", keyed=True + ) if not isinstance(self.files, list): self.files = [self.files] if self.files is not None else [] @@ -565,11 +592,15 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.pathologicalStage is not None and not isinstance(self.pathologicalStage, OntologyClass): self.pathologicalStage = OntologyClass(**as_dict(self.pathologicalStage)) - self._normalize_inlined_as_dict(slot_name="pathologicalTnmFinding", slot_type=OntologyClass, key_name="id", keyed=True) + self._normalize_inlined_as_dict( + slot_name="pathologicalTnmFinding", slot_type=OntologyClass, key_name="id", keyed=True + ) if not isinstance(self.phenotypicFeatures, list): self.phenotypicFeatures = [self.phenotypicFeatures] if self.phenotypicFeatures is not None else [] - self.phenotypicFeatures = [v if isinstance(v, PhenotypicFeature) else PhenotypicFeature(**as_dict(v)) for v in self.phenotypicFeatures] + self.phenotypicFeatures = [ + v if isinstance(v, PhenotypicFeature) else PhenotypicFeature(**as_dict(v)) for v in self.phenotypicFeatures + ] if self.procedure is not None and not isinstance(self.procedure, Procedure): self.procedure = Procedure(**as_dict(self.procedure)) @@ -606,6 +637,7 @@ class Disease(YAMLRoot): """ Message to indicate a disease (diagnosis) and its recorded onset. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = DISEASE.Disease @@ -613,8 +645,12 @@ class Disease(YAMLRoot): class_name: ClassVar[str] = "Disease" class_model_uri: ClassVar[URIRef] = PHENOPACKETS.Disease - clinicalTnmFinding: Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]] = empty_dict() - diseaseStage: Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]] = empty_dict() + clinicalTnmFinding: Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ] = empty_dict() + diseaseStage: Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ] = empty_dict() excluded: Optional[Union[bool, Bool]] = None laterality: Optional[Union[dict, OntologyClass]] = None onset: Optional[Union[dict, TimeElement]] = None @@ -623,7 +659,9 @@ class Disease(YAMLRoot): term: Optional[Union[dict, OntologyClass]] = None def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): - self._normalize_inlined_as_dict(slot_name="clinicalTnmFinding", slot_type=OntologyClass, key_name="id", keyed=True) + self._normalize_inlined_as_dict( + slot_name="clinicalTnmFinding", slot_type=OntologyClass, key_name="id", keyed=True + ) self._normalize_inlined_as_dict(slot_name="diseaseStage", slot_type=OntologyClass, key_name="id", keyed=True) @@ -658,15 +696,22 @@ class Diagnosis(YAMLRoot): class_model_uri: ClassVar[URIRef] = PHENOPACKETS.Diagnosis disease: Optional[Union[dict, OntologyClass]] = None - genomicInterpretations: Optional[Union[Union[dict, "GenomicInterpretation"], list[Union[dict, "GenomicInterpretation"]]]] = empty_list() + genomicInterpretations: Optional[ + Union[Union[dict, "GenomicInterpretation"], list[Union[dict, "GenomicInterpretation"]]] + ] = empty_list() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.disease is not None and not isinstance(self.disease, OntologyClass): self.disease = OntologyClass(**as_dict(self.disease)) if not isinstance(self.genomicInterpretations, list): - self.genomicInterpretations = [self.genomicInterpretations] if self.genomicInterpretations is not None else [] - self.genomicInterpretations = [v if isinstance(v, GenomicInterpretation) else GenomicInterpretation(**as_dict(v)) for v in self.genomicInterpretations] + self.genomicInterpretations = ( + [self.genomicInterpretations] if self.genomicInterpretations is not None else [] + ) + self.genomicInterpretations = [ + v if isinstance(v, GenomicInterpretation) else GenomicInterpretation(**as_dict(v)) + for v in self.genomicInterpretations + ] super().__post_init__(**kwargs) @@ -677,6 +722,7 @@ class GenomicInterpretation(YAMLRoot): A statement about the contribution of a genomic element towards the observed phenotype. Note that this does not intend to encode any knowledge or results of specific computations. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = INTERPRETATION.GenomicInterpretation @@ -749,10 +795,14 @@ class VariantInterpretation(YAMLRoot): variationDescriptor: Optional[Union[dict, "VariationDescriptor"]] = None def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): - if self.acmgPathogenicityClassification is not None and not isinstance(self.acmgPathogenicityClassification, AcmgPathogenicityClassification): + if self.acmgPathogenicityClassification is not None and not isinstance( + self.acmgPathogenicityClassification, AcmgPathogenicityClassification + ): self.acmgPathogenicityClassification = AcmgPathogenicityClassification(self.acmgPathogenicityClassification) - if self.therapeuticActionability is not None and not isinstance(self.therapeuticActionability, TherapeuticActionability): + if self.therapeuticActionability is not None and not isinstance( + self.therapeuticActionability, TherapeuticActionability + ): self.therapeuticActionability = TherapeuticActionability(self.therapeuticActionability) if self.variationDescriptor is not None and not isinstance(self.variationDescriptor, VariationDescriptor): @@ -767,6 +817,7 @@ class Individual(YAMLRoot): An individual (or subject) typically corresponds to an individual human or another organism. FHIR mapping: Patient (https://www.hl7.org/fhir/patient.html). """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = INDIVIDUAL.Individual @@ -860,7 +911,9 @@ class ComplexValue(YAMLRoot): def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.typedQuantities, list): self.typedQuantities = [self.typedQuantities] if self.typedQuantities is not None else [] - self.typedQuantities = [v if isinstance(v, TypedQuantity) else TypedQuantity(**as_dict(v)) for v in self.typedQuantities] + self.typedQuantities = [ + v if isinstance(v, TypedQuantity) else TypedQuantity(**as_dict(v)) for v in self.typedQuantities + ] super().__post_init__(**kwargs) @@ -870,6 +923,7 @@ class Measurement(YAMLRoot): """ FHIR mapping: Observation (https://www.hl7.org/fhir/observation.html) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEASUREMENT.Measurement @@ -964,6 +1018,7 @@ class TypedQuantity(YAMLRoot): For complex measurements, such as blood pressure where more than one component quantity is required to describe the measurement """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEASUREMENT.TypedQuantity @@ -1011,6 +1066,7 @@ class DoseInterval(YAMLRoot): """ e.g. 50mg/ml 3 times daily for two weeks """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEDICAL_ACTION.DoseInterval @@ -1040,6 +1096,7 @@ class MedicalAction(YAMLRoot): """ medication, procedure, other actions taken for clinical management """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEDICAL_ACTION.MedicalAction @@ -1047,7 +1104,9 @@ class MedicalAction(YAMLRoot): class_name: ClassVar[str] = "MedicalAction" class_model_uri: ClassVar[URIRef] = PHENOPACKETS.MedicalAction - adverseEvents: Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]] = empty_dict() + adverseEvents: Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ] = empty_dict() procedure: Optional[Union[dict, Procedure]] = None radiationTherapy: Optional[Union[dict, "RadiationTherapy"]] = None responseToTreatment: Optional[Union[dict, OntologyClass]] = None @@ -1081,7 +1140,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.treatmentTarget is not None and not isinstance(self.treatmentTarget, OntologyClass): self.treatmentTarget = OntologyClass(**as_dict(self.treatmentTarget)) - if self.treatmentTerminationReason is not None and not isinstance(self.treatmentTerminationReason, OntologyClass): + if self.treatmentTerminationReason is not None and not isinstance( + self.treatmentTerminationReason, OntologyClass + ): self.treatmentTerminationReason = OntologyClass(**as_dict(self.treatmentTerminationReason)) super().__post_init__(**kwargs) @@ -1092,6 +1153,7 @@ class RadiationTherapy(YAMLRoot): """ RadiationTherapy """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEDICAL_ACTION.RadiationTherapy @@ -1133,6 +1195,7 @@ class TherapeuticRegimen(YAMLRoot): """ ARGO mapping radiation::radiation_therapy_type (missing) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEDICAL_ACTION.TherapeuticRegimen @@ -1170,6 +1233,7 @@ class Treatment(YAMLRoot): """ ARGO mapping treatment::is_primary_treatment (missing) treatment with an agent, such as a drug """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = MEDICAL_ACTION.Treatment @@ -1192,7 +1256,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.doseIntervals, list): self.doseIntervals = [self.doseIntervals] if self.doseIntervals is not None else [] - self.doseIntervals = [v if isinstance(v, DoseInterval) else DoseInterval(**as_dict(v)) for v in self.doseIntervals] + self.doseIntervals = [ + v if isinstance(v, DoseInterval) else DoseInterval(**as_dict(v)) for v in self.doseIntervals + ] if self.drugType is not None and not isinstance(self.drugType, DrugType): self.drugType = DrugType(self.drugType) @@ -1214,7 +1280,9 @@ class MetaData(YAMLRoot): created: Optional[str] = None createdBy: Optional[str] = None - externalReferences: Optional[Union[Union[dict, ExternalReference], list[Union[dict, ExternalReference]]]] = empty_list() + externalReferences: Optional[Union[Union[dict, ExternalReference], list[Union[dict, ExternalReference]]]] = ( + empty_list() + ) phenopacketSchemaVersion: Optional[str] = None resources: Optional[Union[Union[dict, "Resource"], list[Union[dict, "Resource"]]]] = empty_list() submittedBy: Optional[str] = None @@ -1229,7 +1297,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if not isinstance(self.externalReferences, list): self.externalReferences = [self.externalReferences] if self.externalReferences is not None else [] - self.externalReferences = [v if isinstance(v, ExternalReference) else ExternalReference(**as_dict(v)) for v in self.externalReferences] + self.externalReferences = [ + v if isinstance(v, ExternalReference) else ExternalReference(**as_dict(v)) for v in self.externalReferences + ] if self.phenopacketSchemaVersion is not None and not isinstance(self.phenopacketSchemaVersion, str): self.phenopacketSchemaVersion = str(self.phenopacketSchemaVersion) @@ -1252,6 +1322,7 @@ class Resource(YAMLRoot): Description of an external resource used for referencing an object. For example the resource may be an ontology such as the HPO or SNOMED. FHIR mapping: CodeSystem (http://www.hl7.org/fhir/codesystem.html) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = META_DATA.Resource @@ -1294,6 +1365,7 @@ class Update(YAMLRoot): Information about when an update to a record occurred, who or what made the update and any pertinent information regarding the content and/or reason for the update """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = META_DATA.Update @@ -1325,6 +1397,7 @@ class Pedigree(YAMLRoot): """ https://software.broadinstitute.org/gatk/documentation/article?id=11016 """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PEDIGREE.Pedigree @@ -1387,6 +1460,7 @@ class PhenotypicFeature(YAMLRoot): and frequency FHIR mapping: Condition (https://www.hl7.org/fhir/condition.html) or Observation (https://www.hl7.org/fhir/observation.html) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = PHENOTYPIC_FEATURE.PhenotypicFeature @@ -1397,7 +1471,9 @@ class PhenotypicFeature(YAMLRoot): description: Optional[str] = None evidence: Optional[Union[Union[dict, Evidence], list[Union[dict, Evidence]]]] = empty_list() excluded: Optional[Union[bool, Bool]] = None - modifiers: Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]] = empty_dict() + modifiers: Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ] = empty_dict() onset: Optional[Union[dict, TimeElement]] = None resolution: Optional[Union[dict, TimeElement]] = None severity: Optional[Union[dict, OntologyClass]] = None @@ -1469,6 +1545,7 @@ class Timestamp(YAMLRoot): http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D ) to obtain a formatter capable of generating timestamps in this format. """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = TIMESTAMP.Timestamp @@ -1494,6 +1571,7 @@ class Expression(YAMLRoot): """ https://vrsatile.readthedocs.io/en/latest/value_object_descriptor/vod_index.html#expression """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = VRSATILE.Expression @@ -1523,6 +1601,7 @@ class Extension(YAMLRoot): """ https://vrsatile.readthedocs.io/en/latest/value_object_descriptor/vod_index.html#extension """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = VRSATILE.Extension @@ -1549,6 +1628,7 @@ class GeneDescriptor(YAMLRoot): """ https://vrsatile.readthedocs.io/en/latest/value_object_descriptor/vod_index.html#gene-descriptor """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = VRSATILE.GeneDescriptor @@ -1733,6 +1813,7 @@ class Any(YAMLRoot): adding a field `value` which holds the custom JSON in addition to the `@type` field. Example (for message [google.protobuf.Duration][]): { "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = ANY.Any @@ -1795,16 +1876,22 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.curie is not None and not isinstance(self.curie, str): self.curie = str(self.curie) - if self.derivedSequenceExpression is not None and not isinstance(self.derivedSequenceExpression, DerivedSequenceExpression): + if self.derivedSequenceExpression is not None and not isinstance( + self.derivedSequenceExpression, DerivedSequenceExpression + ): self.derivedSequenceExpression = DerivedSequenceExpression(**as_dict(self.derivedSequenceExpression)) if self.id is not None and not isinstance(self.id, str): self.id = str(self.id) - if self.literalSequenceExpression is not None and not isinstance(self.literalSequenceExpression, LiteralSequenceExpression): + if self.literalSequenceExpression is not None and not isinstance( + self.literalSequenceExpression, LiteralSequenceExpression + ): self.literalSequenceExpression = LiteralSequenceExpression(**as_dict(self.literalSequenceExpression)) - if self.repeatedSequenceExpression is not None and not isinstance(self.repeatedSequenceExpression, RepeatedSequenceExpression): + if self.repeatedSequenceExpression is not None and not isinstance( + self.repeatedSequenceExpression, RepeatedSequenceExpression + ): self.repeatedSequenceExpression = RepeatedSequenceExpression(**as_dict(self.repeatedSequenceExpression)) if self.sequenceLocation is not None and not isinstance(self.sequenceLocation, SequenceLocation): @@ -1874,7 +1961,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.definiteRange is not None and not isinstance(self.definiteRange, DefiniteRange): self.definiteRange = DefiniteRange(**as_dict(self.definiteRange)) - if self.derivedSequenceExpression is not None and not isinstance(self.derivedSequenceExpression, DerivedSequenceExpression): + if self.derivedSequenceExpression is not None and not isinstance( + self.derivedSequenceExpression, DerivedSequenceExpression + ): self.derivedSequenceExpression = DerivedSequenceExpression(**as_dict(self.derivedSequenceExpression)) if self.gene is not None and not isinstance(self.gene, Gene): @@ -1889,13 +1978,17 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.indefiniteRange is not None and not isinstance(self.indefiniteRange, IndefiniteRange): self.indefiniteRange = IndefiniteRange(**as_dict(self.indefiniteRange)) - if self.literalSequenceExpression is not None and not isinstance(self.literalSequenceExpression, LiteralSequenceExpression): + if self.literalSequenceExpression is not None and not isinstance( + self.literalSequenceExpression, LiteralSequenceExpression + ): self.literalSequenceExpression = LiteralSequenceExpression(**as_dict(self.literalSequenceExpression)) if self.number is not None and not isinstance(self.number, Number): self.number = Number(**as_dict(self.number)) - if self.repeatedSequenceExpression is not None and not isinstance(self.repeatedSequenceExpression, RepeatedSequenceExpression): + if self.repeatedSequenceExpression is not None and not isinstance( + self.repeatedSequenceExpression, RepeatedSequenceExpression + ): self.repeatedSequenceExpression = RepeatedSequenceExpression(**as_dict(self.repeatedSequenceExpression)) super().__post_init__(**kwargs) @@ -2180,13 +2273,17 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.definiteRange is not None and not isinstance(self.definiteRange, DefiniteRange): self.definiteRange = DefiniteRange(**as_dict(self.definiteRange)) - if self.derivedSequenceExpression is not None and not isinstance(self.derivedSequenceExpression, DerivedSequenceExpression): + if self.derivedSequenceExpression is not None and not isinstance( + self.derivedSequenceExpression, DerivedSequenceExpression + ): self.derivedSequenceExpression = DerivedSequenceExpression(**as_dict(self.derivedSequenceExpression)) if self.indefiniteRange is not None and not isinstance(self.indefiniteRange, IndefiniteRange): self.indefiniteRange = IndefiniteRange(**as_dict(self.indefiniteRange)) - if self.literalSequenceExpression is not None and not isinstance(self.literalSequenceExpression, LiteralSequenceExpression): + if self.literalSequenceExpression is not None and not isinstance( + self.literalSequenceExpression, LiteralSequenceExpression + ): self.literalSequenceExpression = LiteralSequenceExpression(**as_dict(self.literalSequenceExpression)) if self.number is not None and not isinstance(self.number, Number): @@ -2209,13 +2306,19 @@ class SequenceExpression(YAMLRoot): repeatedSequenceExpression: Optional[Union[dict, RepeatedSequenceExpression]] = None def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): - if self.derivedSequenceExpression is not None and not isinstance(self.derivedSequenceExpression, DerivedSequenceExpression): + if self.derivedSequenceExpression is not None and not isinstance( + self.derivedSequenceExpression, DerivedSequenceExpression + ): self.derivedSequenceExpression = DerivedSequenceExpression(**as_dict(self.derivedSequenceExpression)) - if self.literalSequenceExpression is not None and not isinstance(self.literalSequenceExpression, LiteralSequenceExpression): + if self.literalSequenceExpression is not None and not isinstance( + self.literalSequenceExpression, LiteralSequenceExpression + ): self.literalSequenceExpression = LiteralSequenceExpression(**as_dict(self.literalSequenceExpression)) - if self.repeatedSequenceExpression is not None and not isinstance(self.repeatedSequenceExpression, RepeatedSequenceExpression): + if self.repeatedSequenceExpression is not None and not isinstance( + self.repeatedSequenceExpression, RepeatedSequenceExpression + ): self.repeatedSequenceExpression = RepeatedSequenceExpression(**as_dict(self.repeatedSequenceExpression)) super().__post_init__(**kwargs) @@ -2436,87 +2539,105 @@ class MondoDiseaseTerms(EnumDefinitionImpl): Mondo Disease Ontology provides a comprehensive logically structured ontology of diseases that integrates multiple other disease ontologies. """ + _defn = EnumDefinition( name="MondoDiseaseTerms", description="Mondo Disease Ontology provides a comprehensive logically structured ontology of diseases that integrates multiple other disease ontologies.", ) + class NCITDiseaseTerms(EnumDefinitionImpl): """ All disease terms from the NCI Thesaurus """ + _defn = EnumDefinition( name="NCITDiseaseTerms", description="All disease terms from the NCI Thesaurus", ) + class NCITNeoplasmTerms(EnumDefinitionImpl): """ All neoplasm terms from the NCI Thesaurus """ + _defn = EnumDefinition( name="NCITNeoplasmTerms", description="All neoplasm terms from the NCI Thesaurus", ) + class HPOAbnormalityTerms(EnumDefinitionImpl): """ The Human Phenotype Ontology (HPO) provides a comprehensive logical standard to describe and computationally analyze phenotypic abnormalities found in human disease. """ + _defn = EnumDefinition( name="HPOAbnormalityTerms", description="The Human Phenotype Ontology (HPO) provides a comprehensive logical standard to describe and computationally analyze phenotypic abnormalities found in human disease.", ) + class UberonAnatomicalEntityTerms(EnumDefinitionImpl): """ UBERON is an integrated cross-species ontology with classes representing a variety of anatomical entities. """ + _defn = EnumDefinition( name="UberonAnatomicalEntityTerms", description="UBERON is an integrated cross-species ontology with classes representing a variety of anatomical entities.", ) + class HGNCGeneTerms(EnumDefinitionImpl): """ The HUGO Gene Nomenclature Committee (HGNC) provides standard names, symbols, and IDs for human genes. """ + _defn = EnumDefinition( name="HGNCGeneTerms", description="The HUGO Gene Nomenclature Committee (HGNC) provides standard names, symbols, and IDs for human genes.", ) + class UOUnitTerms(EnumDefinitionImpl): """ The Units of measurement ontology (denoted UO) provides terms for units commonly encountered in medical data. The following table shows some typical examples. """ + _defn = EnumDefinition( name="UOUnitTerms", description="The Units of measurement ontology (denoted UO) provides terms for units commonly encountered in medical data. The following table shows some typical examples.", ) + class GENOZygosityTerms(EnumDefinitionImpl): """ GENO is an ontology of genotypes their more fundamental sequence components. This enum refers to the zygosity subset of GENO """ + _defn = EnumDefinition( name="GENOZygosityTerms", description="GENO is an ontology of genotypes their more fundamental sequence components. This enum refers to the zygosity subset of GENO", ) + class LOINCMeasurementTerms(EnumDefinitionImpl): """ Logical Observation Identifiers Names and Codes (LOINC) is a database and universal standard for identifying medical laboratory observations. It can be used to denote clinical assays in the Measurement element. examples: """ + _defn = EnumDefinition( name="LOINCMeasurementTerms", description="Logical Observation Identifiers Names and Codes (LOINC) is a database and universal standard for identifying medical laboratory observations. It can be used to denote clinical assays in the Measurement element. examples:", ) + class AcmgPathogenicityClassification(EnumDefinitionImpl): BENIGN = PermissibleValue(text="BENIGN") @@ -2530,6 +2651,7 @@ class AcmgPathogenicityClassification(EnumDefinitionImpl): name="AcmgPathogenicityClassification", ) + class InterpretationStatus(EnumDefinitionImpl): CANDIDATE = PermissibleValue(text="CANDIDATE") @@ -2542,6 +2664,7 @@ class InterpretationStatus(EnumDefinitionImpl): name="InterpretationStatus", ) + class ProgressStatus(EnumDefinitionImpl): COMPLETED = PermissibleValue(text="COMPLETED") @@ -2554,6 +2677,7 @@ class ProgressStatus(EnumDefinitionImpl): name="ProgressStatus", ) + class TherapeuticActionability(EnumDefinitionImpl): ACTIONABLE = PermissibleValue(text="ACTIONABLE") @@ -2564,10 +2688,12 @@ class TherapeuticActionability(EnumDefinitionImpl): name="TherapeuticActionability", ) + class KaryotypicSex(EnumDefinitionImpl): """ Karyotypic sex of the individual """ + OTHER_KARYOTYPE = PermissibleValue(text="OTHER_KARYOTYPE") UNKNOWN_KARYOTYPE = PermissibleValue(text="UNKNOWN_KARYOTYPE") XO = PermissibleValue(text="XO") @@ -2585,29 +2711,31 @@ class KaryotypicSex(EnumDefinitionImpl): description="Karyotypic sex of the individual", ) + class Sex(EnumDefinitionImpl): """ Sex of an individual FHIR mapping: AdministrativeGender (https://www.hl7.org/fhir/codesystem-administrative-gender.html) """ - FEMALE = PermissibleValue(text="FEMALE", - description="Female") - MALE = PermissibleValue(text="MALE", - description="Male") - OTHER_SEX = PermissibleValue(text="OTHER_SEX", - description="It is not possible, to accurately assess the applicability of MALE/FEMALE.") - UNKNOWN_SEX = PermissibleValue(text="UNKNOWN_SEX", - description="Not assessed / available.") + + FEMALE = PermissibleValue(text="FEMALE", description="Female") + MALE = PermissibleValue(text="MALE", description="Male") + OTHER_SEX = PermissibleValue( + text="OTHER_SEX", description="It is not possible, to accurately assess the applicability of MALE/FEMALE." + ) + UNKNOWN_SEX = PermissibleValue(text="UNKNOWN_SEX", description="Not assessed / available.") _defn = EnumDefinition( name="Sex", description="Sex of an individual FHIR mapping: AdministrativeGender (https://www.hl7.org/fhir/codesystem-administrative-gender.html)", ) + class Status(EnumDefinitionImpl): """ Default = false i.e. the individual is alive. MUST be true if """ + ALIVE = PermissibleValue(text="ALIVE") DECEASED = PermissibleValue(text="DECEASED") UNKNOWN_STATUS = PermissibleValue(text="UNKNOWN_STATUS") @@ -2617,10 +2745,12 @@ class Status(EnumDefinitionImpl): description="Default = false i.e. the individual is alive. MUST be true if", ) + class DrugType(EnumDefinitionImpl): """ A simplified version of ODHSI-DRUG_EXPOSURE """ + ADMINISTRATION_RELATED_TO_PROCEDURE = PermissibleValue(text="ADMINISTRATION_RELATED_TO_PROCEDURE") EHR_MEDICATION_LIST = PermissibleValue(text="EHR_MEDICATION_LIST") PRESCRIPTION = PermissibleValue(text="PRESCRIPTION") @@ -2631,6 +2761,7 @@ class DrugType(EnumDefinitionImpl): description="A simplified version of ODHSI-DRUG_EXPOSURE", ) + class RegimenStatus(EnumDefinitionImpl): COMPLETED = PermissibleValue(text="COMPLETED") @@ -2642,6 +2773,7 @@ class RegimenStatus(EnumDefinitionImpl): name="RegimenStatus", ) + class AffectedStatus(EnumDefinitionImpl): AFFECTED = PermissibleValue(text="AFFECTED") @@ -2652,424 +2784,271 @@ class AffectedStatus(EnumDefinitionImpl): name="AffectedStatus", ) + class AllelicStateTerms(EnumDefinitionImpl): - HETEROZYGOUS = PermissibleValue(text="HETEROZYGOUS", - description="heterozygous", - meaning=GENO["0000135"]) - HOMOZYGOUS = PermissibleValue(text="HOMOZYGOUS", - description="homozygous", - meaning=GENO["0000136"]) - HEMIZYGOUS = PermissibleValue(text="HEMIZYGOUS", - description="hemizygous", - meaning=GENO["0000134"]) + HETEROZYGOUS = PermissibleValue(text="HETEROZYGOUS", description="heterozygous", meaning=GENO["0000135"]) + HOMOZYGOUS = PermissibleValue(text="HOMOZYGOUS", description="homozygous", meaning=GENO["0000136"]) + HEMIZYGOUS = PermissibleValue(text="HEMIZYGOUS", description="hemizygous", meaning=GENO["0000134"]) _defn = EnumDefinition( name="AllelicStateTerms", ) + class AssaysTerms(EnumDefinitionImpl): - CREATINE_KINASE = PermissibleValue(text="CREATINE_KINASE", - description="Creatine kinase [Enzymatic activity/volume] in Serum or Plasma", - meaning=LOINC["2157-6"]) + CREATINE_KINASE = PermissibleValue( + text="CREATINE_KINASE", + description="Creatine kinase [Enzymatic activity/volume] in Serum or Plasma", + meaning=LOINC["2157-6"], + ) _defn = EnumDefinition( name="AssaysTerms", ) + class GenderTerms(EnumDefinitionImpl): - IDENTIFIES_AS_MALE = PermissibleValue(text="IDENTIFIES_AS_MALE", - description="Identifies as male", - meaning=LOINC["LA22878-5"]) - IDENTIFIES_AS_FEMALE = PermissibleValue(text="IDENTIFIES_AS_FEMALE", - description="Identifies as female", - meaning=LOINC["LA22879-3"]) - FEMALE_TO_MALE_TRANSSEXUAL = PermissibleValue(text="FEMALE_TO_MALE_TRANSSEXUAL", - description="Female-to-male transsexual", - meaning=LOINC["LA22880-1"]) - MALE_TO_FEMALE_TRANSSEXUAL = PermissibleValue(text="MALE_TO_FEMALE_TRANSSEXUAL", - description="Male-to-female transsexual", - meaning=LOINC["LA22881-9"]) - IDENTIFIES_AS_NON_CONFORMING = PermissibleValue(text="IDENTIFIES_AS_NON_CONFORMING", - description="Identifies as non-conforming", - meaning=LOINC["LA22882-7"]) - OTHER_GENDER = PermissibleValue(text="OTHER_GENDER", - description="other", - meaning=LOINC["LA46-8"]) - ASKED_BUT_UNKNOWN = PermissibleValue(text="ASKED_BUT_UNKNOWN", - description="Asked but unknown", - meaning=LOINC["LA20384-6"]) + IDENTIFIES_AS_MALE = PermissibleValue( + text="IDENTIFIES_AS_MALE", description="Identifies as male", meaning=LOINC["LA22878-5"] + ) + IDENTIFIES_AS_FEMALE = PermissibleValue( + text="IDENTIFIES_AS_FEMALE", description="Identifies as female", meaning=LOINC["LA22879-3"] + ) + FEMALE_TO_MALE_TRANSSEXUAL = PermissibleValue( + text="FEMALE_TO_MALE_TRANSSEXUAL", description="Female-to-male transsexual", meaning=LOINC["LA22880-1"] + ) + MALE_TO_FEMALE_TRANSSEXUAL = PermissibleValue( + text="MALE_TO_FEMALE_TRANSSEXUAL", description="Male-to-female transsexual", meaning=LOINC["LA22881-9"] + ) + IDENTIFIES_AS_NON_CONFORMING = PermissibleValue( + text="IDENTIFIES_AS_NON_CONFORMING", description="Identifies as non-conforming", meaning=LOINC["LA22882-7"] + ) + OTHER_GENDER = PermissibleValue(text="OTHER_GENDER", description="other", meaning=LOINC["LA46-8"]) + ASKED_BUT_UNKNOWN = PermissibleValue( + text="ASKED_BUT_UNKNOWN", description="Asked but unknown", meaning=LOINC["LA20384-6"] + ) _defn = EnumDefinition( name="GenderTerms", ) + class LateralityTerms(EnumDefinitionImpl): - RIGHT = PermissibleValue(text="RIGHT", - description="Right", - meaning=HP["0012834"]) - LEFT = PermissibleValue(text="LEFT", - description="Left", - meaning=HP["0012835"]) - UNILATERAL = PermissibleValue(text="UNILATERAL", - description="Unilateral", - meaning=HP["0012833"]) - BILATERAL = PermissibleValue(text="BILATERAL", - description="Bilateral", - meaning=HP["0012832"]) + RIGHT = PermissibleValue(text="RIGHT", description="Right", meaning=HP["0012834"]) + LEFT = PermissibleValue(text="LEFT", description="Left", meaning=HP["0012835"]) + UNILATERAL = PermissibleValue(text="UNILATERAL", description="Unilateral", meaning=HP["0012833"]) + BILATERAL = PermissibleValue(text="BILATERAL", description="Bilateral", meaning=HP["0012832"]) _defn = EnumDefinition( name="LateralityTerms", ) + class MedicalActionsTerms(EnumDefinitionImpl): - ADVERSE_EVENT = PermissibleValue(text="ADVERSE_EVENT", - description="Adverse Event", - meaning=NCIT.C41331) - FOUR_TIMES_DAILY = PermissibleValue(text="FOUR_TIMES_DAILY", - description="Four Times Daily", - meaning=NCIT.C64530) - INTRA_ARTERIAL = PermissibleValue(text="INTRA_ARTERIAL", - description="Intraarterial Route of Administration", - meaning=NCIT.C38222) - IV_ADMINISTRATION = PermissibleValue(text="IV_ADMINISTRATION", - description="Intravenous Route of Administration", - meaning=NCIT.C38276) - ORAL_ADMINISTRATION = PermissibleValue(text="ORAL_ADMINISTRATION", - description="Oral Route of Administration", - meaning=NCIT.C38288) - ONCE = PermissibleValue(text="ONCE", - description="Once", - meaning=NCIT.C64576) - ONCE_DAILY = PermissibleValue(text="ONCE_DAILY", - description="Once Daily", - meaning=NCIT.C125004) - THREE_TIMES_DAILY = PermissibleValue(text="THREE_TIMES_DAILY", - description="Three Times Daily", - meaning=NCIT.C64527) - TWICE_DAILY = PermissibleValue(text="TWICE_DAILY", - description="Twice Daily", - meaning=NCIT.C64496) + ADVERSE_EVENT = PermissibleValue(text="ADVERSE_EVENT", description="Adverse Event", meaning=NCIT.C41331) + FOUR_TIMES_DAILY = PermissibleValue(text="FOUR_TIMES_DAILY", description="Four Times Daily", meaning=NCIT.C64530) + INTRA_ARTERIAL = PermissibleValue( + text="INTRA_ARTERIAL", description="Intraarterial Route of Administration", meaning=NCIT.C38222 + ) + IV_ADMINISTRATION = PermissibleValue( + text="IV_ADMINISTRATION", description="Intravenous Route of Administration", meaning=NCIT.C38276 + ) + ORAL_ADMINISTRATION = PermissibleValue( + text="ORAL_ADMINISTRATION", description="Oral Route of Administration", meaning=NCIT.C38288 + ) + ONCE = PermissibleValue(text="ONCE", description="Once", meaning=NCIT.C64576) + ONCE_DAILY = PermissibleValue(text="ONCE_DAILY", description="Once Daily", meaning=NCIT.C125004) + THREE_TIMES_DAILY = PermissibleValue(text="THREE_TIMES_DAILY", description="Three Times Daily", meaning=NCIT.C64527) + TWICE_DAILY = PermissibleValue(text="TWICE_DAILY", description="Twice Daily", meaning=NCIT.C64496) _defn = EnumDefinition( name="MedicalActionsTerms", ) + class OnsetTerms(EnumDefinitionImpl): - ANTENATAL_ONSET = PermissibleValue(text="ANTENATAL_ONSET", - description="Antenatal onset", - meaning=HP["0030674"]) - EMBRYONAL_ONSET = PermissibleValue(text="EMBRYONAL_ONSET", - description="Embryonal onset", - meaning=HP["0011460"]) - FETAL_ONSET = PermissibleValue(text="FETAL_ONSET", - description="Fetal onset", - meaning=HP["0011461"]) - LATE_FIRST_TRIMESTER_ONSET = PermissibleValue(text="LATE_FIRST_TRIMESTER_ONSET", - description="Late first trimester onset", - meaning=HP["0034199"]) - SECOND_TRIMESTER_ONSET = PermissibleValue(text="SECOND_TRIMESTER_ONSET", - description="Second trimester onset", - meaning=HP["0034198"]) - THIRD_TRIMESTER_ONSET = PermissibleValue(text="THIRD_TRIMESTER_ONSET", - description="Third trimester onset", - meaning=HP["0034197"]) - CONGENITAL_ONSET = PermissibleValue(text="CONGENITAL_ONSET", - description="Congenital onset", - meaning=HP["0003577"]) - NEONATAL_ONSET = PermissibleValue(text="NEONATAL_ONSET", - description="Neonatal onset", - meaning=HP["0003623"]) - INFANTILE_ONSET = PermissibleValue(text="INFANTILE_ONSET", - description="Infantile onset", - meaning=HP["0003593"]) - CHILDHOOD_ONSET = PermissibleValue(text="CHILDHOOD_ONSET", - description="Childhood onset", - meaning=HP["0011463"]) - JUVENILE_ONSET = PermissibleValue(text="JUVENILE_ONSET", - description="Juvenile onset", - meaning=HP["0003621"]) - ADULT_ONSET = PermissibleValue(text="ADULT_ONSET", - description="Adult onset", - meaning=HP["0003581"]) - YOUNG_ADULT_ONSET = PermissibleValue(text="YOUNG_ADULT_ONSET", - description="Young adult onset", - meaning=HP["0011462"]) - EARLY_YOUNG_ADULT_ONSET = PermissibleValue(text="EARLY_YOUNG_ADULT_ONSET", - description="Early young adult onset", - meaning=HP["0025708"]) - INTERMEDIATE_YOUNG_ADULT_ONSET = PermissibleValue(text="INTERMEDIATE_YOUNG_ADULT_ONSET", - description="Intermediate young adult onset", - meaning=HP["0025709"]) - LATE_YOUNG_ADULT_ONSET = PermissibleValue(text="LATE_YOUNG_ADULT_ONSET", - description="Late young adult onset", - meaning=HP["0025710"]) - MIDDLE_AGE_ONSET = PermissibleValue(text="MIDDLE_AGE_ONSET", - description="Middle age onset", - meaning=HP["0003596"]) - LATE_ONSET = PermissibleValue(text="LATE_ONSET", - description="Late onset", - meaning=HP["0003584"]) + ANTENATAL_ONSET = PermissibleValue(text="ANTENATAL_ONSET", description="Antenatal onset", meaning=HP["0030674"]) + EMBRYONAL_ONSET = PermissibleValue(text="EMBRYONAL_ONSET", description="Embryonal onset", meaning=HP["0011460"]) + FETAL_ONSET = PermissibleValue(text="FETAL_ONSET", description="Fetal onset", meaning=HP["0011461"]) + LATE_FIRST_TRIMESTER_ONSET = PermissibleValue( + text="LATE_FIRST_TRIMESTER_ONSET", description="Late first trimester onset", meaning=HP["0034199"] + ) + SECOND_TRIMESTER_ONSET = PermissibleValue( + text="SECOND_TRIMESTER_ONSET", description="Second trimester onset", meaning=HP["0034198"] + ) + THIRD_TRIMESTER_ONSET = PermissibleValue( + text="THIRD_TRIMESTER_ONSET", description="Third trimester onset", meaning=HP["0034197"] + ) + CONGENITAL_ONSET = PermissibleValue(text="CONGENITAL_ONSET", description="Congenital onset", meaning=HP["0003577"]) + NEONATAL_ONSET = PermissibleValue(text="NEONATAL_ONSET", description="Neonatal onset", meaning=HP["0003623"]) + INFANTILE_ONSET = PermissibleValue(text="INFANTILE_ONSET", description="Infantile onset", meaning=HP["0003593"]) + CHILDHOOD_ONSET = PermissibleValue(text="CHILDHOOD_ONSET", description="Childhood onset", meaning=HP["0011463"]) + JUVENILE_ONSET = PermissibleValue(text="JUVENILE_ONSET", description="Juvenile onset", meaning=HP["0003621"]) + ADULT_ONSET = PermissibleValue(text="ADULT_ONSET", description="Adult onset", meaning=HP["0003581"]) + YOUNG_ADULT_ONSET = PermissibleValue( + text="YOUNG_ADULT_ONSET", description="Young adult onset", meaning=HP["0011462"] + ) + EARLY_YOUNG_ADULT_ONSET = PermissibleValue( + text="EARLY_YOUNG_ADULT_ONSET", description="Early young adult onset", meaning=HP["0025708"] + ) + INTERMEDIATE_YOUNG_ADULT_ONSET = PermissibleValue( + text="INTERMEDIATE_YOUNG_ADULT_ONSET", description="Intermediate young adult onset", meaning=HP["0025709"] + ) + LATE_YOUNG_ADULT_ONSET = PermissibleValue( + text="LATE_YOUNG_ADULT_ONSET", description="Late young adult onset", meaning=HP["0025710"] + ) + MIDDLE_AGE_ONSET = PermissibleValue(text="MIDDLE_AGE_ONSET", description="Middle age onset", meaning=HP["0003596"]) + LATE_ONSET = PermissibleValue(text="LATE_ONSET", description="Late onset", meaning=HP["0003584"]) _defn = EnumDefinition( name="OnsetTerms", ) + class OrganTerms(EnumDefinitionImpl): - BRAIN = PermissibleValue(text="BRAIN", - description="brain", - meaning=UBERON["0000955"]) - CEREBELLUM = PermissibleValue(text="CEREBELLUM", - description="cerebellum", - meaning=UBERON["0002037"]) - EAR = PermissibleValue(text="EAR", - description="ear", - meaning=UBERON["0001690"]) - EYE = PermissibleValue(text="EYE", - description="eye", - meaning=UBERON["0000970"]) - HEART = PermissibleValue(text="HEART", - description="heart", - meaning=UBERON["0002107"]) - KIDNEY = PermissibleValue(text="KIDNEY", - description="kidney", - meaning=UBERON["0002113"]) - LARGE_INTESTINE = PermissibleValue(text="LARGE_INTESTINE", - description="large intestine", - meaning=UBERON["0000059"]) - LIVER = PermissibleValue(text="LIVER", - description="liver", - meaning=UBERON["0002107"]) - LUNG = PermissibleValue(text="LUNG", - description="lung", - meaning=UBERON["0002048"]) - NOSE = PermissibleValue(text="NOSE", - description="nose", - meaning=UBERON["0000004"]) - SMALL_INTESTINE = PermissibleValue(text="SMALL_INTESTINE", - description="small intestine", - meaning=UBERON["0002108"]) - SPINAL_CORD = PermissibleValue(text="SPINAL_CORD", - description="spinal cord", - meaning=UBERON["0002240"]) - SPLEEN = PermissibleValue(text="SPLEEN", - description="spleen", - meaning=UBERON["0002106"]) - TONGUE = PermissibleValue(text="TONGUE", - description="tongue", - meaning=UBERON["0001723"]) - THYMUS = PermissibleValue(text="THYMUS", - description="thymus", - meaning=UBERON["0002370"]) + BRAIN = PermissibleValue(text="BRAIN", description="brain", meaning=UBERON["0000955"]) + CEREBELLUM = PermissibleValue(text="CEREBELLUM", description="cerebellum", meaning=UBERON["0002037"]) + EAR = PermissibleValue(text="EAR", description="ear", meaning=UBERON["0001690"]) + EYE = PermissibleValue(text="EYE", description="eye", meaning=UBERON["0000970"]) + HEART = PermissibleValue(text="HEART", description="heart", meaning=UBERON["0002107"]) + KIDNEY = PermissibleValue(text="KIDNEY", description="kidney", meaning=UBERON["0002113"]) + LARGE_INTESTINE = PermissibleValue(text="LARGE_INTESTINE", description="large intestine", meaning=UBERON["0000059"]) + LIVER = PermissibleValue(text="LIVER", description="liver", meaning=UBERON["0002107"]) + LUNG = PermissibleValue(text="LUNG", description="lung", meaning=UBERON["0002048"]) + NOSE = PermissibleValue(text="NOSE", description="nose", meaning=UBERON["0000004"]) + SMALL_INTESTINE = PermissibleValue(text="SMALL_INTESTINE", description="small intestine", meaning=UBERON["0002108"]) + SPINAL_CORD = PermissibleValue(text="SPINAL_CORD", description="spinal cord", meaning=UBERON["0002240"]) + SPLEEN = PermissibleValue(text="SPLEEN", description="spleen", meaning=UBERON["0002106"]) + TONGUE = PermissibleValue(text="TONGUE", description="tongue", meaning=UBERON["0001723"]) + THYMUS = PermissibleValue(text="THYMUS", description="thymus", meaning=UBERON["0002370"]) _defn = EnumDefinition( name="OrganTerms", ) + class ResponseTerms(EnumDefinitionImpl): - FAVORABLE = PermissibleValue(text="FAVORABLE", - description="Favorable", - meaning=NCIT.C102560) - UNFAVORABLE = PermissibleValue(text="UNFAVORABLE", - description="Unfavorable", - meaning=NCIT.C102561) + FAVORABLE = PermissibleValue(text="FAVORABLE", description="Favorable", meaning=NCIT.C102560) + UNFAVORABLE = PermissibleValue(text="UNFAVORABLE", description="Unfavorable", meaning=NCIT.C102561) _defn = EnumDefinition( name="ResponseTerms", ) + class SpatialPatternTerms(EnumDefinitionImpl): - PREDOMINANT_SMALL_JOINT_LOCALIZATION = PermissibleValue(text="PREDOMINANT_SMALL_JOINT_LOCALIZATION", - description="Predominant small joint localization", - meaning=HP["0032544"]) - POLYCYCLIC = PermissibleValue(text="POLYCYCLIC", - description="Polycyclic", - meaning=HP["0031450"]) - AXIAL = PermissibleValue(text="AXIAL", - description="Axial", - meaning=HP["0025287"]) - PERILOBULAR = PermissibleValue(text="PERILOBULAR", - description="Perilobular", - meaning=HP["0033813"]) - PARASEPTAL = PermissibleValue(text="PARASEPTAL", - description="Paraseptal", - meaning=HP["0033814"]) - BRONCHOCENTRIC = PermissibleValue(text="BRONCHOCENTRIC", - description="Bronchocentric", - meaning=HP["0033815"]) - CENTRILOBULAR = PermissibleValue(text="CENTRILOBULAR", - description="Centrilobular", - meaning=HP["0033816"]) - MILIARY = PermissibleValue(text="MILIARY", - description="Miliary", - meaning=HP["0033817"]) - GENERALIZED = PermissibleValue(text="GENERALIZED", - description="Generalized", - meaning=HP["0012837"]) - PERILYMPHATIC = PermissibleValue(text="PERILYMPHATIC", - description="Perilymphatic", - meaning=HP["0033819"]) - LOCALIZED = PermissibleValue(text="LOCALIZED", - description="Localized", - meaning=HP["0012838"]) - RETICULAR = PermissibleValue(text="RETICULAR", - description="Reticular", - meaning=HP["0033818"]) - DISTAL = PermissibleValue(text="DISTAL", - description="Distal", - meaning=HP["0012839"]) - CENTRAL = PermissibleValue(text="CENTRAL", - description="Central", - meaning=HP["0030645"]) - UPPER_BODY_PREDOMINANCE = PermissibleValue(text="UPPER_BODY_PREDOMINANCE", - description="Upper-body predominance", - meaning=HP["0025290"]) - JOINT_EXTENSOR_SURFACE_LOCALIZATION = PermissibleValue(text="JOINT_EXTENSOR_SURFACE_LOCALIZATION", - description="Joint extensor surface localization", - meaning=HP["0032539"]) - HERPETIFORM = PermissibleValue(text="HERPETIFORM", - description="Herpetiform", - meaning=HP["0025295"]) - MORBILLIFORM = PermissibleValue(text="MORBILLIFORM", - description="Morbilliform", - meaning=HP["0025296"]) - PERICENTRAL = PermissibleValue(text="PERICENTRAL", - description="Pericentral", - meaning=HP["0030649"]) - DERMATOMAL = PermissibleValue(text="DERMATOMAL", - description="Dermatomal", - meaning=HP["0025294"]) - MIDPERIPHERAL = PermissibleValue(text="MIDPERIPHERAL", - description="Midperipheral", - meaning=HP["0030648"]) - DISTRIBUTED_ALONG_BLASCHKO_LINES = PermissibleValue(text="DISTRIBUTED_ALONG_BLASCHKO_LINES", - description="Distributed along Blaschko lines", - meaning=HP["0025293"]) - ACRAL = PermissibleValue(text="ACRAL", - description="Acral", - meaning=HP["0025292"]) - PARACENTRAL = PermissibleValue(text="PARACENTRAL", - description="Paracentral", - meaning=HP["0030647"]) - LATERAL = PermissibleValue(text="LATERAL", - description="Lateral", - meaning=HP["0025275"]) - PERIPHERAL = PermissibleValue(text="PERIPHERAL", - description="Peripheral", - meaning=HP["0030646"]) - LOWER_BODY_PREDOMINANCE = PermissibleValue(text="LOWER_BODY_PREDOMINANCE", - description="Lower-body predominance", - meaning=HP["0025291"]) - DIFFUSE = PermissibleValue(text="DIFFUSE", - description="Diffuse", - meaning=HP["0020034"]) - PROXIMAL = PermissibleValue(text="PROXIMAL", - description="Proximal", - meaning=HP["0012840"]) - APICAL = PermissibleValue(text="APICAL", - description="Apical", - meaning=HP["0033820"]) - FOCAL = PermissibleValue(text="FOCAL", - description="Focal", - meaning=HP["0030650"]) - MULTIFOCAL = PermissibleValue(text="MULTIFOCAL", - description="Multifocal", - meaning=HP["0030651"]) - JOINT_FLEXOR_SURFACE_LOCALIZATION = PermissibleValue(text="JOINT_FLEXOR_SURFACE_LOCALIZATION", - description="Jointflexorsurfacelocalization", - meaning=HP["0032540"]) + PREDOMINANT_SMALL_JOINT_LOCALIZATION = PermissibleValue( + text="PREDOMINANT_SMALL_JOINT_LOCALIZATION", + description="Predominant small joint localization", + meaning=HP["0032544"], + ) + POLYCYCLIC = PermissibleValue(text="POLYCYCLIC", description="Polycyclic", meaning=HP["0031450"]) + AXIAL = PermissibleValue(text="AXIAL", description="Axial", meaning=HP["0025287"]) + PERILOBULAR = PermissibleValue(text="PERILOBULAR", description="Perilobular", meaning=HP["0033813"]) + PARASEPTAL = PermissibleValue(text="PARASEPTAL", description="Paraseptal", meaning=HP["0033814"]) + BRONCHOCENTRIC = PermissibleValue(text="BRONCHOCENTRIC", description="Bronchocentric", meaning=HP["0033815"]) + CENTRILOBULAR = PermissibleValue(text="CENTRILOBULAR", description="Centrilobular", meaning=HP["0033816"]) + MILIARY = PermissibleValue(text="MILIARY", description="Miliary", meaning=HP["0033817"]) + GENERALIZED = PermissibleValue(text="GENERALIZED", description="Generalized", meaning=HP["0012837"]) + PERILYMPHATIC = PermissibleValue(text="PERILYMPHATIC", description="Perilymphatic", meaning=HP["0033819"]) + LOCALIZED = PermissibleValue(text="LOCALIZED", description="Localized", meaning=HP["0012838"]) + RETICULAR = PermissibleValue(text="RETICULAR", description="Reticular", meaning=HP["0033818"]) + DISTAL = PermissibleValue(text="DISTAL", description="Distal", meaning=HP["0012839"]) + CENTRAL = PermissibleValue(text="CENTRAL", description="Central", meaning=HP["0030645"]) + UPPER_BODY_PREDOMINANCE = PermissibleValue( + text="UPPER_BODY_PREDOMINANCE", description="Upper-body predominance", meaning=HP["0025290"] + ) + JOINT_EXTENSOR_SURFACE_LOCALIZATION = PermissibleValue( + text="JOINT_EXTENSOR_SURFACE_LOCALIZATION", + description="Joint extensor surface localization", + meaning=HP["0032539"], + ) + HERPETIFORM = PermissibleValue(text="HERPETIFORM", description="Herpetiform", meaning=HP["0025295"]) + MORBILLIFORM = PermissibleValue(text="MORBILLIFORM", description="Morbilliform", meaning=HP["0025296"]) + PERICENTRAL = PermissibleValue(text="PERICENTRAL", description="Pericentral", meaning=HP["0030649"]) + DERMATOMAL = PermissibleValue(text="DERMATOMAL", description="Dermatomal", meaning=HP["0025294"]) + MIDPERIPHERAL = PermissibleValue(text="MIDPERIPHERAL", description="Midperipheral", meaning=HP["0030648"]) + DISTRIBUTED_ALONG_BLASCHKO_LINES = PermissibleValue( + text="DISTRIBUTED_ALONG_BLASCHKO_LINES", description="Distributed along Blaschko lines", meaning=HP["0025293"] + ) + ACRAL = PermissibleValue(text="ACRAL", description="Acral", meaning=HP["0025292"]) + PARACENTRAL = PermissibleValue(text="PARACENTRAL", description="Paracentral", meaning=HP["0030647"]) + LATERAL = PermissibleValue(text="LATERAL", description="Lateral", meaning=HP["0025275"]) + PERIPHERAL = PermissibleValue(text="PERIPHERAL", description="Peripheral", meaning=HP["0030646"]) + LOWER_BODY_PREDOMINANCE = PermissibleValue( + text="LOWER_BODY_PREDOMINANCE", description="Lower-body predominance", meaning=HP["0025291"] + ) + DIFFUSE = PermissibleValue(text="DIFFUSE", description="Diffuse", meaning=HP["0020034"]) + PROXIMAL = PermissibleValue(text="PROXIMAL", description="Proximal", meaning=HP["0012840"]) + APICAL = PermissibleValue(text="APICAL", description="Apical", meaning=HP["0033820"]) + FOCAL = PermissibleValue(text="FOCAL", description="Focal", meaning=HP["0030650"]) + MULTIFOCAL = PermissibleValue(text="MULTIFOCAL", description="Multifocal", meaning=HP["0030651"]) + JOINT_FLEXOR_SURFACE_LOCALIZATION = PermissibleValue( + text="JOINT_FLEXOR_SURFACE_LOCALIZATION", description="Jointflexorsurfacelocalization", meaning=HP["0032540"] + ) _defn = EnumDefinition( name="SpatialPatternTerms", ) + class UnitTerms(EnumDefinitionImpl): - DEGREE = PermissibleValue(text="DEGREE", - description="degree (plane angle)", - meaning=UCUM.degree) - DIOPTER = PermissibleValue(text="DIOPTER", - description="diopter", - meaning=UCUM["%5Bdiop%5D"]) - GRAM = PermissibleValue(text="GRAM", - description="gram", - meaning=UCUM.g) - GRAM_PER_KG = PermissibleValue(text="GRAM_PER_KG", - description="gram per kilogram", - meaning=UCUM["g/kg"]) - KILIGRAM = PermissibleValue(text="KILIGRAM", - description="kiligram", - meaning=UCUM.kg) - LITER = PermissibleValue(text="LITER", - description="liter", - meaning=UCUM.L) - METER = PermissibleValue(text="METER", - description="meter", - meaning=UCUM.m) - MICROGRAM = PermissibleValue(text="MICROGRAM", - description="microgram", - meaning=UCUM.ug) - MICROGRAM_PER_DECILITER = PermissibleValue(text="MICROGRAM_PER_DECILITER", - description="microgram per deciliter", - meaning=UCUM["ug/dL"]) - MICROGRAM_PER_LITER = PermissibleValue(text="MICROGRAM_PER_LITER", - description="microgram per liter", - meaning=UCUM["ug/L"]) - MICROLITER = PermissibleValue(text="MICROLITER", - description="microliter", - meaning=UCUM.uL) - MICROMETER = PermissibleValue(text="MICROMETER", - description="micrometer", - meaning=UCUM.um) - MILLIGRAM = PermissibleValue(text="MILLIGRAM", - description="milligram", - meaning=UCUM.mg) - MILLIGRAM_PER_DAY = PermissibleValue(text="MILLIGRAM_PER_DAY", - description="milligram per day", - meaning=UCUM["mg/dL"]) - MILLIGRAM_PER_DL = PermissibleValue(text="MILLIGRAM_PER_DL", - description="milligram per deciliter", - meaning=UCUM["mg/dL"]) - MILLIGRAM_PER_KG = PermissibleValue(text="MILLIGRAM_PER_KG", - description="milligram per kilogram", - meaning=UCUM["mg.kg-1"]) - MILLILITER = PermissibleValue(text="MILLILITER", - description="milliliter", - meaning=UCUM.mL) - MILLIMETER = PermissibleValue(text="MILLIMETER", - description="millimeter", - meaning=UCUM.mm) - MILLIMETRES_OF_MERCURY = PermissibleValue(text="MILLIMETRES_OF_MERCURY", - description="millimetres of mercury", - meaning=UCUM["mm%5BHg%5D"]) - MILLIMOLE = PermissibleValue(text="MILLIMOLE", - description="millimole", - meaning=UCUM.mmol) - MOLE = PermissibleValue(text="MOLE", - description="mole", - meaning=UCUM.mol) - MOLE_PER_LITER = PermissibleValue(text="MOLE_PER_LITER", - description="mole per liter", - meaning=UCUM["mol/L"]) - MOLE_PER_MILLILITER = PermissibleValue(text="MOLE_PER_MILLILITER", - description="mole per milliliter", - meaning=UCUM["mol/mL"]) - ENZYME_UNIT_PER_LITER = PermissibleValue(text="ENZYME_UNIT_PER_LITER", - description="enzyme unit per liter", - meaning=UCUM["U/L"]) + DEGREE = PermissibleValue(text="DEGREE", description="degree (plane angle)", meaning=UCUM.degree) + DIOPTER = PermissibleValue(text="DIOPTER", description="diopter", meaning=UCUM["%5Bdiop%5D"]) + GRAM = PermissibleValue(text="GRAM", description="gram", meaning=UCUM.g) + GRAM_PER_KG = PermissibleValue(text="GRAM_PER_KG", description="gram per kilogram", meaning=UCUM["g/kg"]) + KILIGRAM = PermissibleValue(text="KILIGRAM", description="kiligram", meaning=UCUM.kg) + LITER = PermissibleValue(text="LITER", description="liter", meaning=UCUM.L) + METER = PermissibleValue(text="METER", description="meter", meaning=UCUM.m) + MICROGRAM = PermissibleValue(text="MICROGRAM", description="microgram", meaning=UCUM.ug) + MICROGRAM_PER_DECILITER = PermissibleValue( + text="MICROGRAM_PER_DECILITER", description="microgram per deciliter", meaning=UCUM["ug/dL"] + ) + MICROGRAM_PER_LITER = PermissibleValue( + text="MICROGRAM_PER_LITER", description="microgram per liter", meaning=UCUM["ug/L"] + ) + MICROLITER = PermissibleValue(text="MICROLITER", description="microliter", meaning=UCUM.uL) + MICROMETER = PermissibleValue(text="MICROMETER", description="micrometer", meaning=UCUM.um) + MILLIGRAM = PermissibleValue(text="MILLIGRAM", description="milligram", meaning=UCUM.mg) + MILLIGRAM_PER_DAY = PermissibleValue( + text="MILLIGRAM_PER_DAY", description="milligram per day", meaning=UCUM["mg/dL"] + ) + MILLIGRAM_PER_DL = PermissibleValue( + text="MILLIGRAM_PER_DL", description="milligram per deciliter", meaning=UCUM["mg/dL"] + ) + MILLIGRAM_PER_KG = PermissibleValue( + text="MILLIGRAM_PER_KG", description="milligram per kilogram", meaning=UCUM["mg.kg-1"] + ) + MILLILITER = PermissibleValue(text="MILLILITER", description="milliliter", meaning=UCUM.mL) + MILLIMETER = PermissibleValue(text="MILLIMETER", description="millimeter", meaning=UCUM.mm) + MILLIMETRES_OF_MERCURY = PermissibleValue( + text="MILLIMETRES_OF_MERCURY", description="millimetres of mercury", meaning=UCUM["mm%5BHg%5D"] + ) + MILLIMOLE = PermissibleValue(text="MILLIMOLE", description="millimole", meaning=UCUM.mmol) + MOLE = PermissibleValue(text="MOLE", description="mole", meaning=UCUM.mol) + MOLE_PER_LITER = PermissibleValue(text="MOLE_PER_LITER", description="mole per liter", meaning=UCUM["mol/L"]) + MOLE_PER_MILLILITER = PermissibleValue( + text="MOLE_PER_MILLILITER", description="mole per milliliter", meaning=UCUM["mol/mL"] + ) + ENZYME_UNIT_PER_LITER = PermissibleValue( + text="ENZYME_UNIT_PER_LITER", description="enzyme unit per liter", meaning=UCUM["U/L"] + ) _defn = EnumDefinition( name="UnitTerms", ) + class MoleculeContext(EnumDefinitionImpl): genomic = PermissibleValue(text="genomic") @@ -3081,882 +3060,2648 @@ class MoleculeContext(EnumDefinitionImpl): name="MoleculeContext", ) + # Slots class slots: pass -slots.cohort__description = Slot(uri=PHENOPACKETS.description, name="cohort__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.cohort__description, domain=None, range=Optional[str]) - -slots.cohort__files = Slot(uri=PHENOPACKETS.files, name="cohort__files", curie=PHENOPACKETS.curie('files'), - model_uri=PHENOPACKETS.cohort__files, domain=None, range=Optional[Union[Union[dict, File], list[Union[dict, File]]]]) - -slots.cohort__id = Slot(uri=PHENOPACKETS.id, name="cohort__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.cohort__id, domain=None, range=Optional[str]) - -slots.cohort__members = Slot(uri=PHENOPACKETS.members, name="cohort__members", curie=PHENOPACKETS.curie('members'), - model_uri=PHENOPACKETS.cohort__members, domain=None, range=Optional[Union[Union[dict, Phenopacket], list[Union[dict, Phenopacket]]]]) - -slots.cohort__metaData = Slot(uri=PHENOPACKETS.metaData, name="cohort__metaData", curie=PHENOPACKETS.curie('metaData'), - model_uri=PHENOPACKETS.cohort__metaData, domain=None, range=Union[dict, MetaData]) - -slots.family__consanguinousParents = Slot(uri=PHENOPACKETS.consanguinousParents, name="family__consanguinousParents", curie=PHENOPACKETS.curie('consanguinousParents'), - model_uri=PHENOPACKETS.family__consanguinousParents, domain=None, range=Optional[Union[bool, Bool]]) - -slots.family__files = Slot(uri=PHENOPACKETS.files, name="family__files", curie=PHENOPACKETS.curie('files'), - model_uri=PHENOPACKETS.family__files, domain=None, range=Optional[Union[Union[dict, File], list[Union[dict, File]]]]) - -slots.family__id = Slot(uri=PHENOPACKETS.id, name="family__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.family__id, domain=None, range=Optional[str]) - -slots.family__metaData = Slot(uri=PHENOPACKETS.metaData, name="family__metaData", curie=PHENOPACKETS.curie('metaData'), - model_uri=PHENOPACKETS.family__metaData, domain=None, range=Union[dict, MetaData]) - -slots.family__pedigree = Slot(uri=PHENOPACKETS.pedigree, name="family__pedigree", curie=PHENOPACKETS.curie('pedigree'), - model_uri=PHENOPACKETS.family__pedigree, domain=None, range=Optional[Union[dict, Pedigree]]) - -slots.family__proband = Slot(uri=PHENOPACKETS.proband, name="family__proband", curie=PHENOPACKETS.curie('proband'), - model_uri=PHENOPACKETS.family__proband, domain=None, range=Optional[Union[dict, Phenopacket]]) - -slots.family__relatives = Slot(uri=PHENOPACKETS.relatives, name="family__relatives", curie=PHENOPACKETS.curie('relatives'), - model_uri=PHENOPACKETS.family__relatives, domain=None, range=Optional[Union[Union[dict, Phenopacket], list[Union[dict, Phenopacket]]]]) - -slots.phenopacket__biosamples = Slot(uri=PHENOPACKETS.biosamples, name="phenopacket__biosamples", curie=PHENOPACKETS.curie('biosamples'), - model_uri=PHENOPACKETS.phenopacket__biosamples, domain=None, range=Optional[Union[Union[dict, Biosample], list[Union[dict, Biosample]]]]) - -slots.phenopacket__diseases = Slot(uri=PHENOPACKETS.diseases, name="phenopacket__diseases", curie=PHENOPACKETS.curie('diseases'), - model_uri=PHENOPACKETS.phenopacket__diseases, domain=None, range=Optional[Union[Union[dict, Disease], list[Union[dict, Disease]]]]) - -slots.phenopacket__files = Slot(uri=PHENOPACKETS.files, name="phenopacket__files", curie=PHENOPACKETS.curie('files'), - model_uri=PHENOPACKETS.phenopacket__files, domain=None, range=Optional[Union[Union[dict, File], list[Union[dict, File]]]]) - -slots.phenopacket__id = Slot(uri=PHENOPACKETS.id, name="phenopacket__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.phenopacket__id, domain=None, range=Optional[str]) - -slots.phenopacket__interpretations = Slot(uri=PHENOPACKETS.interpretations, name="phenopacket__interpretations", curie=PHENOPACKETS.curie('interpretations'), - model_uri=PHENOPACKETS.phenopacket__interpretations, domain=None, range=Optional[Union[Union[dict, Interpretation], list[Union[dict, Interpretation]]]]) - -slots.phenopacket__measurements = Slot(uri=PHENOPACKETS.measurements, name="phenopacket__measurements", curie=PHENOPACKETS.curie('measurements'), - model_uri=PHENOPACKETS.phenopacket__measurements, domain=None, range=Optional[Union[Union[dict, Measurement], list[Union[dict, Measurement]]]]) - -slots.phenopacket__medicalActions = Slot(uri=PHENOPACKETS.medicalActions, name="phenopacket__medicalActions", curie=PHENOPACKETS.curie('medicalActions'), - model_uri=PHENOPACKETS.phenopacket__medicalActions, domain=None, range=Optional[Union[Union[dict, MedicalAction], list[Union[dict, MedicalAction]]]]) - -slots.phenopacket__metaData = Slot(uri=PHENOPACKETS.metaData, name="phenopacket__metaData", curie=PHENOPACKETS.curie('metaData'), - model_uri=PHENOPACKETS.phenopacket__metaData, domain=None, range=Union[dict, MetaData]) - -slots.phenopacket__phenotypicFeatures = Slot(uri=PHENOPACKETS.phenotypicFeatures, name="phenopacket__phenotypicFeatures", curie=PHENOPACKETS.curie('phenotypicFeatures'), - model_uri=PHENOPACKETS.phenopacket__phenotypicFeatures, domain=None, range=Optional[Union[Union[dict, PhenotypicFeature], list[Union[dict, PhenotypicFeature]]]]) - -slots.phenopacket__subject = Slot(uri=PHENOPACKETS.subject, name="phenopacket__subject", curie=PHENOPACKETS.curie('subject'), - model_uri=PHENOPACKETS.phenopacket__subject, domain=None, range=Optional[Union[dict, Individual]]) - -slots.age__iso8601duration = Slot(uri=PHENOPACKETS.iso8601duration, name="age__iso8601duration", curie=PHENOPACKETS.curie('iso8601duration'), - model_uri=PHENOPACKETS.age__iso8601duration, domain=None, range=Optional[str]) - -slots.ageRange__end = Slot(uri=PHENOPACKETS.end, name="ageRange__end", curie=PHENOPACKETS.curie('end'), - model_uri=PHENOPACKETS.ageRange__end, domain=None, range=Optional[Union[dict, Age]]) - -slots.ageRange__start = Slot(uri=PHENOPACKETS.start, name="ageRange__start", curie=PHENOPACKETS.curie('start'), - model_uri=PHENOPACKETS.ageRange__start, domain=None, range=Optional[Union[dict, Age]]) - -slots.evidence__evidenceCode = Slot(uri=PHENOPACKETS.evidenceCode, name="evidence__evidenceCode", curie=PHENOPACKETS.curie('evidenceCode'), - model_uri=PHENOPACKETS.evidence__evidenceCode, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.evidence__reference = Slot(uri=PHENOPACKETS.reference, name="evidence__reference", curie=PHENOPACKETS.curie('reference'), - model_uri=PHENOPACKETS.evidence__reference, domain=None, range=Optional[Union[dict, ExternalReference]]) - -slots.externalReference__description = Slot(uri=PHENOPACKETS.description, name="externalReference__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.externalReference__description, domain=None, range=Optional[str]) - -slots.externalReference__id = Slot(uri=PHENOPACKETS.id, name="externalReference__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.externalReference__id, domain=None, range=Optional[str]) - -slots.externalReference__reference = Slot(uri=PHENOPACKETS.reference, name="externalReference__reference", curie=PHENOPACKETS.curie('reference'), - model_uri=PHENOPACKETS.externalReference__reference, domain=None, range=Optional[str]) - -slots.file__fileAttributes = Slot(uri=PHENOPACKETS.fileAttributes, name="file__fileAttributes", curie=PHENOPACKETS.curie('fileAttributes'), - model_uri=PHENOPACKETS.file__fileAttributes, domain=None, range=Optional[Union[dict, Dictionary]]) - -slots.file__individualToFileIdentifiers = Slot(uri=PHENOPACKETS.individualToFileIdentifiers, name="file__individualToFileIdentifiers", curie=PHENOPACKETS.curie('individualToFileIdentifiers'), - model_uri=PHENOPACKETS.file__individualToFileIdentifiers, domain=None, range=Optional[Union[dict, Dictionary]]) - -slots.file__uri = Slot(uri=PHENOPACKETS.uri, name="file__uri", curie=PHENOPACKETS.curie('uri'), - model_uri=PHENOPACKETS.file__uri, domain=None, range=Optional[str]) - -slots.gestationalAge__days = Slot(uri=PHENOPACKETS.days, name="gestationalAge__days", curie=PHENOPACKETS.curie('days'), - model_uri=PHENOPACKETS.gestationalAge__days, domain=None, range=Optional[int]) - -slots.gestationalAge__weeks = Slot(uri=PHENOPACKETS.weeks, name="gestationalAge__weeks", curie=PHENOPACKETS.curie('weeks'), - model_uri=PHENOPACKETS.gestationalAge__weeks, domain=None, range=Optional[int]) - -slots.ontologyClass__id = Slot(uri=PHENOPACKETS.id, name="ontologyClass__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.ontologyClass__id, domain=None, range=URIRef) - -slots.ontologyClass__label = Slot(uri=PHENOPACKETS.label, name="ontologyClass__label", curie=PHENOPACKETS.curie('label'), - model_uri=PHENOPACKETS.ontologyClass__label, domain=None, range=Optional[str]) - -slots.procedure__bodySite = Slot(uri=PHENOPACKETS.bodySite, name="procedure__bodySite", curie=PHENOPACKETS.curie('bodySite'), - model_uri=PHENOPACKETS.procedure__bodySite, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.procedure__code = Slot(uri=PHENOPACKETS.code, name="procedure__code", curie=PHENOPACKETS.curie('code'), - model_uri=PHENOPACKETS.procedure__code, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.procedure__performed = Slot(uri=PHENOPACKETS.performed, name="procedure__performed", curie=PHENOPACKETS.curie('performed'), - model_uri=PHENOPACKETS.procedure__performed, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.timeElement__age = Slot(uri=PHENOPACKETS.age, name="timeElement__age", curie=PHENOPACKETS.curie('age'), - model_uri=PHENOPACKETS.timeElement__age, domain=None, range=Optional[Union[dict, Age]]) - -slots.timeElement__ageRange = Slot(uri=PHENOPACKETS.ageRange, name="timeElement__ageRange", curie=PHENOPACKETS.curie('ageRange'), - model_uri=PHENOPACKETS.timeElement__ageRange, domain=None, range=Optional[Union[dict, AgeRange]]) - -slots.timeElement__gestationalAge = Slot(uri=PHENOPACKETS.gestationalAge, name="timeElement__gestationalAge", curie=PHENOPACKETS.curie('gestationalAge'), - model_uri=PHENOPACKETS.timeElement__gestationalAge, domain=None, range=Optional[Union[dict, GestationalAge]]) - -slots.timeElement__interval = Slot(uri=PHENOPACKETS.interval, name="timeElement__interval", curie=PHENOPACKETS.curie('interval'), - model_uri=PHENOPACKETS.timeElement__interval, domain=None, range=Optional[Union[dict, TimeInterval]]) - -slots.timeElement__ontologyClass = Slot(uri=PHENOPACKETS.ontologyClass, name="timeElement__ontologyClass", curie=PHENOPACKETS.curie('ontologyClass'), - model_uri=PHENOPACKETS.timeElement__ontologyClass, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.timeElement__timestamp = Slot(uri=PHENOPACKETS.timestamp, name="timeElement__timestamp", curie=PHENOPACKETS.curie('timestamp'), - model_uri=PHENOPACKETS.timeElement__timestamp, domain=None, range=Optional[str]) - -slots.timeInterval__end = Slot(uri=PHENOPACKETS.end, name="timeInterval__end", curie=PHENOPACKETS.curie('end'), - model_uri=PHENOPACKETS.timeInterval__end, domain=None, range=Optional[str]) - -slots.timeInterval__start = Slot(uri=PHENOPACKETS.start, name="timeInterval__start", curie=PHENOPACKETS.curie('start'), - model_uri=PHENOPACKETS.timeInterval__start, domain=None, range=Optional[str]) - -slots.biosample__derivedFromId = Slot(uri=PHENOPACKETS.derivedFromId, name="biosample__derivedFromId", curie=PHENOPACKETS.curie('derivedFromId'), - model_uri=PHENOPACKETS.biosample__derivedFromId, domain=None, range=Optional[str]) - -slots.biosample__description = Slot(uri=PHENOPACKETS.description, name="biosample__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.biosample__description, domain=None, range=Optional[str]) - -slots.biosample__diagnosticMarkers = Slot(uri=PHENOPACKETS.diagnosticMarkers, name="biosample__diagnosticMarkers", curie=PHENOPACKETS.curie('diagnosticMarkers'), - model_uri=PHENOPACKETS.biosample__diagnosticMarkers, domain=None, range=Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]]) - -slots.biosample__files = Slot(uri=PHENOPACKETS.files, name="biosample__files", curie=PHENOPACKETS.curie('files'), - model_uri=PHENOPACKETS.biosample__files, domain=None, range=Optional[Union[Union[dict, File], list[Union[dict, File]]]]) - -slots.biosample__histologicalDiagnosis = Slot(uri=PHENOPACKETS.histologicalDiagnosis, name="biosample__histologicalDiagnosis", curie=PHENOPACKETS.curie('histologicalDiagnosis'), - model_uri=PHENOPACKETS.biosample__histologicalDiagnosis, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__id = Slot(uri=PHENOPACKETS.id, name="biosample__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.biosample__id, domain=None, range=Optional[str]) - -slots.biosample__individualId = Slot(uri=PHENOPACKETS.individualId, name="biosample__individualId", curie=PHENOPACKETS.curie('individualId'), - model_uri=PHENOPACKETS.biosample__individualId, domain=None, range=Optional[str]) - -slots.biosample__materialSample = Slot(uri=PHENOPACKETS.materialSample, name="biosample__materialSample", curie=PHENOPACKETS.curie('materialSample'), - model_uri=PHENOPACKETS.biosample__materialSample, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__measurements = Slot(uri=PHENOPACKETS.measurements, name="biosample__measurements", curie=PHENOPACKETS.curie('measurements'), - model_uri=PHENOPACKETS.biosample__measurements, domain=None, range=Optional[Union[Union[dict, Measurement], list[Union[dict, Measurement]]]]) - -slots.biosample__pathologicalStage = Slot(uri=PHENOPACKETS.pathologicalStage, name="biosample__pathologicalStage", curie=PHENOPACKETS.curie('pathologicalStage'), - model_uri=PHENOPACKETS.biosample__pathologicalStage, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__pathologicalTnmFinding = Slot(uri=PHENOPACKETS.pathologicalTnmFinding, name="biosample__pathologicalTnmFinding", curie=PHENOPACKETS.curie('pathologicalTnmFinding'), - model_uri=PHENOPACKETS.biosample__pathologicalTnmFinding, domain=None, range=Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]]) - -slots.biosample__phenotypicFeatures = Slot(uri=PHENOPACKETS.phenotypicFeatures, name="biosample__phenotypicFeatures", curie=PHENOPACKETS.curie('phenotypicFeatures'), - model_uri=PHENOPACKETS.biosample__phenotypicFeatures, domain=None, range=Optional[Union[Union[dict, PhenotypicFeature], list[Union[dict, PhenotypicFeature]]]]) - -slots.biosample__procedure = Slot(uri=PHENOPACKETS.procedure, name="biosample__procedure", curie=PHENOPACKETS.curie('procedure'), - model_uri=PHENOPACKETS.biosample__procedure, domain=None, range=Optional[Union[dict, Procedure]]) - -slots.biosample__sampleProcessing = Slot(uri=PHENOPACKETS.sampleProcessing, name="biosample__sampleProcessing", curie=PHENOPACKETS.curie('sampleProcessing'), - model_uri=PHENOPACKETS.biosample__sampleProcessing, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__sampleStorage = Slot(uri=PHENOPACKETS.sampleStorage, name="biosample__sampleStorage", curie=PHENOPACKETS.curie('sampleStorage'), - model_uri=PHENOPACKETS.biosample__sampleStorage, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__sampleType = Slot(uri=PHENOPACKETS.sampleType, name="biosample__sampleType", curie=PHENOPACKETS.curie('sampleType'), - model_uri=PHENOPACKETS.biosample__sampleType, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__sampledTissue = Slot(uri=PHENOPACKETS.sampledTissue, name="biosample__sampledTissue", curie=PHENOPACKETS.curie('sampledTissue'), - model_uri=PHENOPACKETS.biosample__sampledTissue, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__taxonomy = Slot(uri=PHENOPACKETS.taxonomy, name="biosample__taxonomy", curie=PHENOPACKETS.curie('taxonomy'), - model_uri=PHENOPACKETS.biosample__taxonomy, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__timeOfCollection = Slot(uri=PHENOPACKETS.timeOfCollection, name="biosample__timeOfCollection", curie=PHENOPACKETS.curie('timeOfCollection'), - model_uri=PHENOPACKETS.biosample__timeOfCollection, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.biosample__tumorGrade = Slot(uri=PHENOPACKETS.tumorGrade, name="biosample__tumorGrade", curie=PHENOPACKETS.curie('tumorGrade'), - model_uri=PHENOPACKETS.biosample__tumorGrade, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.biosample__tumorProgression = Slot(uri=PHENOPACKETS.tumorProgression, name="biosample__tumorProgression", curie=PHENOPACKETS.curie('tumorProgression'), - model_uri=PHENOPACKETS.biosample__tumorProgression, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.disease__clinicalTnmFinding = Slot(uri=PHENOPACKETS.clinicalTnmFinding, name="disease__clinicalTnmFinding", curie=PHENOPACKETS.curie('clinicalTnmFinding'), - model_uri=PHENOPACKETS.disease__clinicalTnmFinding, domain=None, range=Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]]) - -slots.disease__diseaseStage = Slot(uri=PHENOPACKETS.diseaseStage, name="disease__diseaseStage", curie=PHENOPACKETS.curie('diseaseStage'), - model_uri=PHENOPACKETS.disease__diseaseStage, domain=None, range=Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]]) - -slots.disease__excluded = Slot(uri=PHENOPACKETS.excluded, name="disease__excluded", curie=PHENOPACKETS.curie('excluded'), - model_uri=PHENOPACKETS.disease__excluded, domain=None, range=Optional[Union[bool, Bool]]) - -slots.disease__laterality = Slot(uri=PHENOPACKETS.laterality, name="disease__laterality", curie=PHENOPACKETS.curie('laterality'), - model_uri=PHENOPACKETS.disease__laterality, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.disease__onset = Slot(uri=PHENOPACKETS.onset, name="disease__onset", curie=PHENOPACKETS.curie('onset'), - model_uri=PHENOPACKETS.disease__onset, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.disease__primarySite = Slot(uri=PHENOPACKETS.primarySite, name="disease__primarySite", curie=PHENOPACKETS.curie('primarySite'), - model_uri=PHENOPACKETS.disease__primarySite, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.disease__resolution = Slot(uri=PHENOPACKETS.resolution, name="disease__resolution", curie=PHENOPACKETS.curie('resolution'), - model_uri=PHENOPACKETS.disease__resolution, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.disease__term = Slot(uri=PHENOPACKETS.term, name="disease__term", curie=PHENOPACKETS.curie('term'), - model_uri=PHENOPACKETS.disease__term, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.diagnosis__disease = Slot(uri=PHENOPACKETS.disease, name="diagnosis__disease", curie=PHENOPACKETS.curie('disease'), - model_uri=PHENOPACKETS.diagnosis__disease, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.diagnosis__genomicInterpretations = Slot(uri=PHENOPACKETS.genomicInterpretations, name="diagnosis__genomicInterpretations", curie=PHENOPACKETS.curie('genomicInterpretations'), - model_uri=PHENOPACKETS.diagnosis__genomicInterpretations, domain=None, range=Optional[Union[Union[dict, GenomicInterpretation], list[Union[dict, GenomicInterpretation]]]]) - -slots.genomicInterpretation__gene = Slot(uri=PHENOPACKETS.gene, name="genomicInterpretation__gene", curie=PHENOPACKETS.curie('gene'), - model_uri=PHENOPACKETS.genomicInterpretation__gene, domain=None, range=Optional[Union[dict, GeneDescriptor]]) - -slots.genomicInterpretation__interpretationStatus = Slot(uri=PHENOPACKETS.interpretationStatus, name="genomicInterpretation__interpretationStatus", curie=PHENOPACKETS.curie('interpretationStatus'), - model_uri=PHENOPACKETS.genomicInterpretation__interpretationStatus, domain=None, range=Optional[Union[str, "InterpretationStatus"]]) - -slots.genomicInterpretation__subjectOrBiosampleId = Slot(uri=PHENOPACKETS.subjectOrBiosampleId, name="genomicInterpretation__subjectOrBiosampleId", curie=PHENOPACKETS.curie('subjectOrBiosampleId'), - model_uri=PHENOPACKETS.genomicInterpretation__subjectOrBiosampleId, domain=None, range=Optional[str]) - -slots.genomicInterpretation__variantInterpretation = Slot(uri=PHENOPACKETS.variantInterpretation, name="genomicInterpretation__variantInterpretation", curie=PHENOPACKETS.curie('variantInterpretation'), - model_uri=PHENOPACKETS.genomicInterpretation__variantInterpretation, domain=None, range=Optional[Union[dict, VariantInterpretation]]) - -slots.interpretation__diagnosis = Slot(uri=PHENOPACKETS.diagnosis, name="interpretation__diagnosis", curie=PHENOPACKETS.curie('diagnosis'), - model_uri=PHENOPACKETS.interpretation__diagnosis, domain=None, range=Optional[Union[dict, Diagnosis]]) - -slots.interpretation__id = Slot(uri=PHENOPACKETS.id, name="interpretation__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.interpretation__id, domain=None, range=Optional[str]) - -slots.interpretation__progressStatus = Slot(uri=PHENOPACKETS.progressStatus, name="interpretation__progressStatus", curie=PHENOPACKETS.curie('progressStatus'), - model_uri=PHENOPACKETS.interpretation__progressStatus, domain=None, range=Optional[Union[str, "ProgressStatus"]]) - -slots.interpretation__summary = Slot(uri=PHENOPACKETS.summary, name="interpretation__summary", curie=PHENOPACKETS.curie('summary'), - model_uri=PHENOPACKETS.interpretation__summary, domain=None, range=Optional[str]) - -slots.variantInterpretation__acmgPathogenicityClassification = Slot(uri=PHENOPACKETS.acmgPathogenicityClassification, name="variantInterpretation__acmgPathogenicityClassification", curie=PHENOPACKETS.curie('acmgPathogenicityClassification'), - model_uri=PHENOPACKETS.variantInterpretation__acmgPathogenicityClassification, domain=None, range=Optional[Union[str, "AcmgPathogenicityClassification"]]) - -slots.variantInterpretation__therapeuticActionability = Slot(uri=PHENOPACKETS.therapeuticActionability, name="variantInterpretation__therapeuticActionability", curie=PHENOPACKETS.curie('therapeuticActionability'), - model_uri=PHENOPACKETS.variantInterpretation__therapeuticActionability, domain=None, range=Optional[Union[str, "TherapeuticActionability"]]) - -slots.variantInterpretation__variationDescriptor = Slot(uri=PHENOPACKETS.variationDescriptor, name="variantInterpretation__variationDescriptor", curie=PHENOPACKETS.curie('variationDescriptor'), - model_uri=PHENOPACKETS.variantInterpretation__variationDescriptor, domain=None, range=Optional[Union[dict, VariationDescriptor]]) - -slots.individual__alternateIds = Slot(uri=PHENOPACKETS.alternateIds, name="individual__alternateIds", curie=PHENOPACKETS.curie('alternateIds'), - model_uri=PHENOPACKETS.individual__alternateIds, domain=None, range=Optional[Union[str, list[str]]]) - -slots.individual__dateOfBirth = Slot(uri=PHENOPACKETS.dateOfBirth, name="individual__dateOfBirth", curie=PHENOPACKETS.curie('dateOfBirth'), - model_uri=PHENOPACKETS.individual__dateOfBirth, domain=None, range=Optional[str]) - -slots.individual__gender = Slot(uri=PHENOPACKETS.gender, name="individual__gender", curie=PHENOPACKETS.curie('gender'), - model_uri=PHENOPACKETS.individual__gender, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.individual__id = Slot(uri=PHENOPACKETS.id, name="individual__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.individual__id, domain=None, range=Optional[str]) - -slots.individual__karyotypicSex = Slot(uri=PHENOPACKETS.karyotypicSex, name="individual__karyotypicSex", curie=PHENOPACKETS.curie('karyotypicSex'), - model_uri=PHENOPACKETS.individual__karyotypicSex, domain=None, range=Optional[Union[str, "KaryotypicSex"]]) - -slots.individual__sex = Slot(uri=PHENOPACKETS.sex, name="individual__sex", curie=PHENOPACKETS.curie('sex'), - model_uri=PHENOPACKETS.individual__sex, domain=None, range=Optional[Union[str, "Sex"]]) - -slots.individual__taxonomy = Slot(uri=PHENOPACKETS.taxonomy, name="individual__taxonomy", curie=PHENOPACKETS.curie('taxonomy'), - model_uri=PHENOPACKETS.individual__taxonomy, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.individual__timeAtLastEncounter = Slot(uri=PHENOPACKETS.timeAtLastEncounter, name="individual__timeAtLastEncounter", curie=PHENOPACKETS.curie('timeAtLastEncounter'), - model_uri=PHENOPACKETS.individual__timeAtLastEncounter, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.individual__vitalStatus = Slot(uri=PHENOPACKETS.vitalStatus, name="individual__vitalStatus", curie=PHENOPACKETS.curie('vitalStatus'), - model_uri=PHENOPACKETS.individual__vitalStatus, domain=None, range=Optional[Union[dict, VitalStatus]]) - -slots.vitalStatus__causeOfDeath = Slot(uri=PHENOPACKETS.causeOfDeath, name="vitalStatus__causeOfDeath", curie=PHENOPACKETS.curie('causeOfDeath'), - model_uri=PHENOPACKETS.vitalStatus__causeOfDeath, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.vitalStatus__status = Slot(uri=PHENOPACKETS.status, name="vitalStatus__status", curie=PHENOPACKETS.curie('status'), - model_uri=PHENOPACKETS.vitalStatus__status, domain=None, range=Optional[Union[str, "Status"]]) - -slots.vitalStatus__survivalTimeInDays = Slot(uri=PHENOPACKETS.survivalTimeInDays, name="vitalStatus__survivalTimeInDays", curie=PHENOPACKETS.curie('survivalTimeInDays'), - model_uri=PHENOPACKETS.vitalStatus__survivalTimeInDays, domain=None, range=Optional[int]) - -slots.vitalStatus__timeOfDeath = Slot(uri=PHENOPACKETS.timeOfDeath, name="vitalStatus__timeOfDeath", curie=PHENOPACKETS.curie('timeOfDeath'), - model_uri=PHENOPACKETS.vitalStatus__timeOfDeath, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.complexValue__typedQuantities = Slot(uri=PHENOPACKETS.typedQuantities, name="complexValue__typedQuantities", curie=PHENOPACKETS.curie('typedQuantities'), - model_uri=PHENOPACKETS.complexValue__typedQuantities, domain=None, range=Optional[Union[Union[dict, TypedQuantity], list[Union[dict, TypedQuantity]]]]) - -slots.measurement__assay = Slot(uri=PHENOPACKETS.assay, name="measurement__assay", curie=PHENOPACKETS.curie('assay'), - model_uri=PHENOPACKETS.measurement__assay, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.measurement__complexValue = Slot(uri=PHENOPACKETS.complexValue, name="measurement__complexValue", curie=PHENOPACKETS.curie('complexValue'), - model_uri=PHENOPACKETS.measurement__complexValue, domain=None, range=Optional[Union[dict, ComplexValue]]) - -slots.measurement__description = Slot(uri=PHENOPACKETS.description, name="measurement__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.measurement__description, domain=None, range=Optional[str]) - -slots.measurement__procedure = Slot(uri=PHENOPACKETS.procedure, name="measurement__procedure", curie=PHENOPACKETS.curie('procedure'), - model_uri=PHENOPACKETS.measurement__procedure, domain=None, range=Optional[Union[dict, Procedure]]) - -slots.measurement__timeObserved = Slot(uri=PHENOPACKETS.timeObserved, name="measurement__timeObserved", curie=PHENOPACKETS.curie('timeObserved'), - model_uri=PHENOPACKETS.measurement__timeObserved, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.measurement__value = Slot(uri=PHENOPACKETS.value, name="measurement__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.measurement__value, domain=None, range=Optional[Union[dict, Value]]) - -slots.quantity__referenceRange = Slot(uri=PHENOPACKETS.referenceRange, name="quantity__referenceRange", curie=PHENOPACKETS.curie('referenceRange'), - model_uri=PHENOPACKETS.quantity__referenceRange, domain=None, range=Optional[Union[dict, ReferenceRange]]) - -slots.quantity__unit = Slot(uri=PHENOPACKETS.unit, name="quantity__unit", curie=PHENOPACKETS.curie('unit'), - model_uri=PHENOPACKETS.quantity__unit, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.quantity__value = Slot(uri=PHENOPACKETS.value, name="quantity__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.quantity__value, domain=None, range=Optional[float]) - -slots.referenceRange__high = Slot(uri=PHENOPACKETS.high, name="referenceRange__high", curie=PHENOPACKETS.curie('high'), - model_uri=PHENOPACKETS.referenceRange__high, domain=None, range=Optional[float]) - -slots.referenceRange__low = Slot(uri=PHENOPACKETS.low, name="referenceRange__low", curie=PHENOPACKETS.curie('low'), - model_uri=PHENOPACKETS.referenceRange__low, domain=None, range=Optional[float]) - -slots.referenceRange__unit = Slot(uri=PHENOPACKETS.unit, name="referenceRange__unit", curie=PHENOPACKETS.curie('unit'), - model_uri=PHENOPACKETS.referenceRange__unit, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.typedQuantity__quantity = Slot(uri=PHENOPACKETS.quantity, name="typedQuantity__quantity", curie=PHENOPACKETS.curie('quantity'), - model_uri=PHENOPACKETS.typedQuantity__quantity, domain=None, range=Optional[Union[dict, Quantity]]) - -slots.typedQuantity__type = Slot(uri=PHENOPACKETS.type, name="typedQuantity__type", curie=PHENOPACKETS.curie('type'), - model_uri=PHENOPACKETS.typedQuantity__type, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.value__ontologyClass = Slot(uri=PHENOPACKETS.ontologyClass, name="value__ontologyClass", curie=PHENOPACKETS.curie('ontologyClass'), - model_uri=PHENOPACKETS.value__ontologyClass, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.value__quantity = Slot(uri=PHENOPACKETS.quantity, name="value__quantity", curie=PHENOPACKETS.curie('quantity'), - model_uri=PHENOPACKETS.value__quantity, domain=None, range=Optional[Union[dict, Quantity]]) - -slots.doseInterval__interval = Slot(uri=PHENOPACKETS.interval, name="doseInterval__interval", curie=PHENOPACKETS.curie('interval'), - model_uri=PHENOPACKETS.doseInterval__interval, domain=None, range=Optional[Union[dict, TimeInterval]]) - -slots.doseInterval__quantity = Slot(uri=PHENOPACKETS.quantity, name="doseInterval__quantity", curie=PHENOPACKETS.curie('quantity'), - model_uri=PHENOPACKETS.doseInterval__quantity, domain=None, range=Optional[Union[dict, Quantity]]) - -slots.doseInterval__scheduleFrequency = Slot(uri=PHENOPACKETS.scheduleFrequency, name="doseInterval__scheduleFrequency", curie=PHENOPACKETS.curie('scheduleFrequency'), - model_uri=PHENOPACKETS.doseInterval__scheduleFrequency, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.medicalAction__adverseEvents = Slot(uri=PHENOPACKETS.adverseEvents, name="medicalAction__adverseEvents", curie=PHENOPACKETS.curie('adverseEvents'), - model_uri=PHENOPACKETS.medicalAction__adverseEvents, domain=None, range=Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]]) - -slots.medicalAction__procedure = Slot(uri=PHENOPACKETS.procedure, name="medicalAction__procedure", curie=PHENOPACKETS.curie('procedure'), - model_uri=PHENOPACKETS.medicalAction__procedure, domain=None, range=Optional[Union[dict, Procedure]]) - -slots.medicalAction__radiationTherapy = Slot(uri=PHENOPACKETS.radiationTherapy, name="medicalAction__radiationTherapy", curie=PHENOPACKETS.curie('radiationTherapy'), - model_uri=PHENOPACKETS.medicalAction__radiationTherapy, domain=None, range=Optional[Union[dict, RadiationTherapy]]) - -slots.medicalAction__responseToTreatment = Slot(uri=PHENOPACKETS.responseToTreatment, name="medicalAction__responseToTreatment", curie=PHENOPACKETS.curie('responseToTreatment'), - model_uri=PHENOPACKETS.medicalAction__responseToTreatment, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.medicalAction__therapeuticRegimen = Slot(uri=PHENOPACKETS.therapeuticRegimen, name="medicalAction__therapeuticRegimen", curie=PHENOPACKETS.curie('therapeuticRegimen'), - model_uri=PHENOPACKETS.medicalAction__therapeuticRegimen, domain=None, range=Optional[Union[dict, TherapeuticRegimen]]) - -slots.medicalAction__treatment = Slot(uri=PHENOPACKETS.treatment, name="medicalAction__treatment", curie=PHENOPACKETS.curie('treatment'), - model_uri=PHENOPACKETS.medicalAction__treatment, domain=None, range=Optional[Union[dict, Treatment]]) - -slots.medicalAction__treatmentIntent = Slot(uri=PHENOPACKETS.treatmentIntent, name="medicalAction__treatmentIntent", curie=PHENOPACKETS.curie('treatmentIntent'), - model_uri=PHENOPACKETS.medicalAction__treatmentIntent, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.medicalAction__treatmentTarget = Slot(uri=PHENOPACKETS.treatmentTarget, name="medicalAction__treatmentTarget", curie=PHENOPACKETS.curie('treatmentTarget'), - model_uri=PHENOPACKETS.medicalAction__treatmentTarget, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.medicalAction__treatmentTerminationReason = Slot(uri=PHENOPACKETS.treatmentTerminationReason, name="medicalAction__treatmentTerminationReason", curie=PHENOPACKETS.curie('treatmentTerminationReason'), - model_uri=PHENOPACKETS.medicalAction__treatmentTerminationReason, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.radiationTherapy__bodySite = Slot(uri=PHENOPACKETS.bodySite, name="radiationTherapy__bodySite", curie=PHENOPACKETS.curie('bodySite'), - model_uri=PHENOPACKETS.radiationTherapy__bodySite, domain=None, range=Union[dict, OntologyClass]) - -slots.radiationTherapy__dosage = Slot(uri=PHENOPACKETS.dosage, name="radiationTherapy__dosage", curie=PHENOPACKETS.curie('dosage'), - model_uri=PHENOPACKETS.radiationTherapy__dosage, domain=None, range=int) - -slots.radiationTherapy__fractions = Slot(uri=PHENOPACKETS.fractions, name="radiationTherapy__fractions", curie=PHENOPACKETS.curie('fractions'), - model_uri=PHENOPACKETS.radiationTherapy__fractions, domain=None, range=int) - -slots.radiationTherapy__modality = Slot(uri=PHENOPACKETS.modality, name="radiationTherapy__modality", curie=PHENOPACKETS.curie('modality'), - model_uri=PHENOPACKETS.radiationTherapy__modality, domain=None, range=Union[dict, OntologyClass]) - -slots.therapeuticRegimen__endTime = Slot(uri=PHENOPACKETS.endTime, name="therapeuticRegimen__endTime", curie=PHENOPACKETS.curie('endTime'), - model_uri=PHENOPACKETS.therapeuticRegimen__endTime, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.therapeuticRegimen__externalReference = Slot(uri=PHENOPACKETS.externalReference, name="therapeuticRegimen__externalReference", curie=PHENOPACKETS.curie('externalReference'), - model_uri=PHENOPACKETS.therapeuticRegimen__externalReference, domain=None, range=Optional[Union[dict, ExternalReference]]) - -slots.therapeuticRegimen__ontologyClass = Slot(uri=PHENOPACKETS.ontologyClass, name="therapeuticRegimen__ontologyClass", curie=PHENOPACKETS.curie('ontologyClass'), - model_uri=PHENOPACKETS.therapeuticRegimen__ontologyClass, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.therapeuticRegimen__regimenStatus = Slot(uri=PHENOPACKETS.regimenStatus, name="therapeuticRegimen__regimenStatus", curie=PHENOPACKETS.curie('regimenStatus'), - model_uri=PHENOPACKETS.therapeuticRegimen__regimenStatus, domain=None, range=Optional[Union[str, "RegimenStatus"]]) - -slots.therapeuticRegimen__startTime = Slot(uri=PHENOPACKETS.startTime, name="therapeuticRegimen__startTime", curie=PHENOPACKETS.curie('startTime'), - model_uri=PHENOPACKETS.therapeuticRegimen__startTime, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.treatment__agent = Slot(uri=PHENOPACKETS.agent, name="treatment__agent", curie=PHENOPACKETS.curie('agent'), - model_uri=PHENOPACKETS.treatment__agent, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.treatment__cumulativeDose = Slot(uri=PHENOPACKETS.cumulativeDose, name="treatment__cumulativeDose", curie=PHENOPACKETS.curie('cumulativeDose'), - model_uri=PHENOPACKETS.treatment__cumulativeDose, domain=None, range=Optional[Union[dict, Quantity]]) - -slots.treatment__doseIntervals = Slot(uri=PHENOPACKETS.doseIntervals, name="treatment__doseIntervals", curie=PHENOPACKETS.curie('doseIntervals'), - model_uri=PHENOPACKETS.treatment__doseIntervals, domain=None, range=Optional[Union[Union[dict, DoseInterval], list[Union[dict, DoseInterval]]]]) - -slots.treatment__drugType = Slot(uri=PHENOPACKETS.drugType, name="treatment__drugType", curie=PHENOPACKETS.curie('drugType'), - model_uri=PHENOPACKETS.treatment__drugType, domain=None, range=Optional[Union[str, "DrugType"]]) - -slots.treatment__routeOfAdministration = Slot(uri=PHENOPACKETS.routeOfAdministration, name="treatment__routeOfAdministration", curie=PHENOPACKETS.curie('routeOfAdministration'), - model_uri=PHENOPACKETS.treatment__routeOfAdministration, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.metaData__created = Slot(uri=PHENOPACKETS.created, name="metaData__created", curie=PHENOPACKETS.curie('created'), - model_uri=PHENOPACKETS.metaData__created, domain=None, range=Optional[str]) - -slots.metaData__createdBy = Slot(uri=PHENOPACKETS.createdBy, name="metaData__createdBy", curie=PHENOPACKETS.curie('createdBy'), - model_uri=PHENOPACKETS.metaData__createdBy, domain=None, range=Optional[str]) - -slots.metaData__externalReferences = Slot(uri=PHENOPACKETS.externalReferences, name="metaData__externalReferences", curie=PHENOPACKETS.curie('externalReferences'), - model_uri=PHENOPACKETS.metaData__externalReferences, domain=None, range=Optional[Union[Union[dict, ExternalReference], list[Union[dict, ExternalReference]]]]) - -slots.metaData__phenopacketSchemaVersion = Slot(uri=PHENOPACKETS.phenopacketSchemaVersion, name="metaData__phenopacketSchemaVersion", curie=PHENOPACKETS.curie('phenopacketSchemaVersion'), - model_uri=PHENOPACKETS.metaData__phenopacketSchemaVersion, domain=None, range=Optional[str]) - -slots.metaData__resources = Slot(uri=PHENOPACKETS.resources, name="metaData__resources", curie=PHENOPACKETS.curie('resources'), - model_uri=PHENOPACKETS.metaData__resources, domain=None, range=Optional[Union[Union[dict, Resource], list[Union[dict, Resource]]]]) - -slots.metaData__submittedBy = Slot(uri=PHENOPACKETS.submittedBy, name="metaData__submittedBy", curie=PHENOPACKETS.curie('submittedBy'), - model_uri=PHENOPACKETS.metaData__submittedBy, domain=None, range=Optional[str]) - -slots.metaData__updates = Slot(uri=PHENOPACKETS.updates, name="metaData__updates", curie=PHENOPACKETS.curie('updates'), - model_uri=PHENOPACKETS.metaData__updates, domain=None, range=Optional[Union[Union[dict, Update], list[Union[dict, Update]]]]) - -slots.resource__id = Slot(uri=PHENOPACKETS.id, name="resource__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.resource__id, domain=None, range=Optional[str]) - -slots.resource__iriPrefix = Slot(uri=PHENOPACKETS.iriPrefix, name="resource__iriPrefix", curie=PHENOPACKETS.curie('iriPrefix'), - model_uri=PHENOPACKETS.resource__iriPrefix, domain=None, range=Optional[str]) - -slots.resource__name = Slot(uri=PHENOPACKETS.name, name="resource__name", curie=PHENOPACKETS.curie('name'), - model_uri=PHENOPACKETS.resource__name, domain=None, range=Optional[str]) - -slots.resource__namespacePrefix = Slot(uri=PHENOPACKETS.namespacePrefix, name="resource__namespacePrefix", curie=PHENOPACKETS.curie('namespacePrefix'), - model_uri=PHENOPACKETS.resource__namespacePrefix, domain=None, range=Optional[str]) - -slots.resource__url = Slot(uri=PHENOPACKETS.url, name="resource__url", curie=PHENOPACKETS.curie('url'), - model_uri=PHENOPACKETS.resource__url, domain=None, range=Optional[str]) - -slots.resource__version = Slot(uri=PHENOPACKETS.version, name="resource__version", curie=PHENOPACKETS.curie('version'), - model_uri=PHENOPACKETS.resource__version, domain=None, range=Optional[str]) - -slots.update__comment = Slot(uri=PHENOPACKETS.comment, name="update__comment", curie=PHENOPACKETS.curie('comment'), - model_uri=PHENOPACKETS.update__comment, domain=None, range=Optional[str]) - -slots.update__timestamp = Slot(uri=PHENOPACKETS.timestamp, name="update__timestamp", curie=PHENOPACKETS.curie('timestamp'), - model_uri=PHENOPACKETS.update__timestamp, domain=None, range=str) - -slots.update__updatedBy = Slot(uri=PHENOPACKETS.updatedBy, name="update__updatedBy", curie=PHENOPACKETS.curie('updatedBy'), - model_uri=PHENOPACKETS.update__updatedBy, domain=None, range=Optional[str]) - -slots.pedigree__persons = Slot(uri=PHENOPACKETS.persons, name="pedigree__persons", curie=PHENOPACKETS.curie('persons'), - model_uri=PHENOPACKETS.pedigree__persons, domain=None, range=Optional[Union[Union[dict, Person], list[Union[dict, Person]]]]) - -slots.person__affectedStatus = Slot(uri=PHENOPACKETS.affectedStatus, name="person__affectedStatus", curie=PHENOPACKETS.curie('affectedStatus'), - model_uri=PHENOPACKETS.person__affectedStatus, domain=None, range=Optional[Union[str, "AffectedStatus"]]) - -slots.person__familyId = Slot(uri=PHENOPACKETS.familyId, name="person__familyId", curie=PHENOPACKETS.curie('familyId'), - model_uri=PHENOPACKETS.person__familyId, domain=None, range=Optional[str]) - -slots.person__individualId = Slot(uri=PHENOPACKETS.individualId, name="person__individualId", curie=PHENOPACKETS.curie('individualId'), - model_uri=PHENOPACKETS.person__individualId, domain=None, range=Optional[str]) - -slots.person__maternalId = Slot(uri=PHENOPACKETS.maternalId, name="person__maternalId", curie=PHENOPACKETS.curie('maternalId'), - model_uri=PHENOPACKETS.person__maternalId, domain=None, range=Optional[str]) - -slots.person__paternalId = Slot(uri=PHENOPACKETS.paternalId, name="person__paternalId", curie=PHENOPACKETS.curie('paternalId'), - model_uri=PHENOPACKETS.person__paternalId, domain=None, range=Optional[str]) - -slots.person__sex = Slot(uri=PHENOPACKETS.sex, name="person__sex", curie=PHENOPACKETS.curie('sex'), - model_uri=PHENOPACKETS.person__sex, domain=None, range=Optional[Union[str, "Sex"]]) - -slots.phenotypicFeature__description = Slot(uri=PHENOPACKETS.description, name="phenotypicFeature__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.phenotypicFeature__description, domain=None, range=Optional[str]) - -slots.phenotypicFeature__evidence = Slot(uri=PHENOPACKETS.evidence, name="phenotypicFeature__evidence", curie=PHENOPACKETS.curie('evidence'), - model_uri=PHENOPACKETS.phenotypicFeature__evidence, domain=None, range=Optional[Union[Union[dict, Evidence], list[Union[dict, Evidence]]]]) - -slots.phenotypicFeature__excluded = Slot(uri=PHENOPACKETS.excluded, name="phenotypicFeature__excluded", curie=PHENOPACKETS.curie('excluded'), - model_uri=PHENOPACKETS.phenotypicFeature__excluded, domain=None, range=Optional[Union[bool, Bool]]) - -slots.phenotypicFeature__modifiers = Slot(uri=PHENOPACKETS.modifiers, name="phenotypicFeature__modifiers", curie=PHENOPACKETS.curie('modifiers'), - model_uri=PHENOPACKETS.phenotypicFeature__modifiers, domain=None, range=Optional[Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]]]) - -slots.phenotypicFeature__onset = Slot(uri=PHENOPACKETS.onset, name="phenotypicFeature__onset", curie=PHENOPACKETS.curie('onset'), - model_uri=PHENOPACKETS.phenotypicFeature__onset, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.phenotypicFeature__resolution = Slot(uri=PHENOPACKETS.resolution, name="phenotypicFeature__resolution", curie=PHENOPACKETS.curie('resolution'), - model_uri=PHENOPACKETS.phenotypicFeature__resolution, domain=None, range=Optional[Union[dict, TimeElement]]) - -slots.phenotypicFeature__severity = Slot(uri=PHENOPACKETS.severity, name="phenotypicFeature__severity", curie=PHENOPACKETS.curie('severity'), - model_uri=PHENOPACKETS.phenotypicFeature__severity, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.phenotypicFeature__type = Slot(uri=PHENOPACKETS.type, name="phenotypicFeature__type", curie=PHENOPACKETS.curie('type'), - model_uri=PHENOPACKETS.phenotypicFeature__type, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.timestamp__nanos = Slot(uri=PHENOPACKETS.nanos, name="timestamp__nanos", curie=PHENOPACKETS.curie('nanos'), - model_uri=PHENOPACKETS.timestamp__nanos, domain=None, range=Optional[int]) - -slots.timestamp__seconds = Slot(uri=PHENOPACKETS.seconds, name="timestamp__seconds", curie=PHENOPACKETS.curie('seconds'), - model_uri=PHENOPACKETS.timestamp__seconds, domain=None, range=Optional[int]) - -slots.expression__syntax = Slot(uri=PHENOPACKETS.syntax, name="expression__syntax", curie=PHENOPACKETS.curie('syntax'), - model_uri=PHENOPACKETS.expression__syntax, domain=None, range=Optional[str]) - -slots.expression__value = Slot(uri=PHENOPACKETS.value, name="expression__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.expression__value, domain=None, range=Optional[str]) - -slots.expression__version = Slot(uri=PHENOPACKETS.version, name="expression__version", curie=PHENOPACKETS.curie('version'), - model_uri=PHENOPACKETS.expression__version, domain=None, range=Optional[str]) - -slots.extension__name = Slot(uri=PHENOPACKETS.name, name="extension__name", curie=PHENOPACKETS.curie('name'), - model_uri=PHENOPACKETS.extension__name, domain=None, range=Optional[str]) - -slots.extension__value = Slot(uri=PHENOPACKETS.value, name="extension__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.extension__value, domain=None, range=Optional[Union[Union[dict, Any], list[Union[dict, Any]]]]) - -slots.geneDescriptor__alternateIds = Slot(uri=PHENOPACKETS.alternateIds, name="geneDescriptor__alternateIds", curie=PHENOPACKETS.curie('alternateIds'), - model_uri=PHENOPACKETS.geneDescriptor__alternateIds, domain=None, range=Optional[Union[str, list[str]]]) - -slots.geneDescriptor__alternateSymbols = Slot(uri=PHENOPACKETS.alternateSymbols, name="geneDescriptor__alternateSymbols", curie=PHENOPACKETS.curie('alternateSymbols'), - model_uri=PHENOPACKETS.geneDescriptor__alternateSymbols, domain=None, range=Optional[Union[str, list[str]]]) - -slots.geneDescriptor__description = Slot(uri=PHENOPACKETS.description, name="geneDescriptor__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.geneDescriptor__description, domain=None, range=Optional[str]) - -slots.geneDescriptor__symbol = Slot(uri=PHENOPACKETS.symbol, name="geneDescriptor__symbol", curie=PHENOPACKETS.curie('symbol'), - model_uri=PHENOPACKETS.geneDescriptor__symbol, domain=None, range=Optional[str]) - -slots.geneDescriptor__valueId = Slot(uri=PHENOPACKETS.valueId, name="geneDescriptor__valueId", curie=PHENOPACKETS.curie('valueId'), - model_uri=PHENOPACKETS.geneDescriptor__valueId, domain=None, range=Optional[str]) - -slots.geneDescriptor__xrefs = Slot(uri=PHENOPACKETS.xrefs, name="geneDescriptor__xrefs", curie=PHENOPACKETS.curie('xrefs'), - model_uri=PHENOPACKETS.geneDescriptor__xrefs, domain=None, range=Optional[Union[str, list[str]]]) - -slots.variationDescriptor__allelicState = Slot(uri=PHENOPACKETS.allelicState, name="variationDescriptor__allelicState", curie=PHENOPACKETS.curie('allelicState'), - model_uri=PHENOPACKETS.variationDescriptor__allelicState, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.variationDescriptor__alternateLabels = Slot(uri=PHENOPACKETS.alternateLabels, name="variationDescriptor__alternateLabels", curie=PHENOPACKETS.curie('alternateLabels'), - model_uri=PHENOPACKETS.variationDescriptor__alternateLabels, domain=None, range=Optional[Union[str, list[str]]]) - -slots.variationDescriptor__description = Slot(uri=PHENOPACKETS.description, name="variationDescriptor__description", curie=PHENOPACKETS.curie('description'), - model_uri=PHENOPACKETS.variationDescriptor__description, domain=None, range=Optional[str]) - -slots.variationDescriptor__expressions = Slot(uri=PHENOPACKETS.expressions, name="variationDescriptor__expressions", curie=PHENOPACKETS.curie('expressions'), - model_uri=PHENOPACKETS.variationDescriptor__expressions, domain=None, range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]]) - -slots.variationDescriptor__extensions = Slot(uri=PHENOPACKETS.extensions, name="variationDescriptor__extensions", curie=PHENOPACKETS.curie('extensions'), - model_uri=PHENOPACKETS.variationDescriptor__extensions, domain=None, range=Optional[Union[Union[dict, Extension], list[Union[dict, Extension]]]]) - -slots.variationDescriptor__geneContext = Slot(uri=PHENOPACKETS.geneContext, name="variationDescriptor__geneContext", curie=PHENOPACKETS.curie('geneContext'), - model_uri=PHENOPACKETS.variationDescriptor__geneContext, domain=None, range=Optional[Union[dict, GeneDescriptor]]) - -slots.variationDescriptor__id = Slot(uri=PHENOPACKETS.id, name="variationDescriptor__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.variationDescriptor__id, domain=None, range=Optional[str]) - -slots.variationDescriptor__label = Slot(uri=PHENOPACKETS.label, name="variationDescriptor__label", curie=PHENOPACKETS.curie('label'), - model_uri=PHENOPACKETS.variationDescriptor__label, domain=None, range=Optional[str]) - -slots.variationDescriptor__moleculeContext = Slot(uri=PHENOPACKETS.moleculeContext, name="variationDescriptor__moleculeContext", curie=PHENOPACKETS.curie('moleculeContext'), - model_uri=PHENOPACKETS.variationDescriptor__moleculeContext, domain=None, range=Optional[Union[str, "MoleculeContext"]]) - -slots.variationDescriptor__structuralType = Slot(uri=PHENOPACKETS.structuralType, name="variationDescriptor__structuralType", curie=PHENOPACKETS.curie('structuralType'), - model_uri=PHENOPACKETS.variationDescriptor__structuralType, domain=None, range=Optional[Union[dict, OntologyClass]]) - -slots.variationDescriptor__variation = Slot(uri=PHENOPACKETS.variation, name="variationDescriptor__variation", curie=PHENOPACKETS.curie('variation'), - model_uri=PHENOPACKETS.variationDescriptor__variation, domain=None, range=Optional[Union[dict, Variation]]) - -slots.variationDescriptor__vcfRecord = Slot(uri=PHENOPACKETS.vcfRecord, name="variationDescriptor__vcfRecord", curie=PHENOPACKETS.curie('vcfRecord'), - model_uri=PHENOPACKETS.variationDescriptor__vcfRecord, domain=None, range=Optional[Union[dict, VcfRecord]]) - -slots.variationDescriptor__vrsRefAlleleSeq = Slot(uri=PHENOPACKETS.vrsRefAlleleSeq, name="variationDescriptor__vrsRefAlleleSeq", curie=PHENOPACKETS.curie('vrsRefAlleleSeq'), - model_uri=PHENOPACKETS.variationDescriptor__vrsRefAlleleSeq, domain=None, range=Optional[str]) - -slots.variationDescriptor__xrefs = Slot(uri=PHENOPACKETS.xrefs, name="variationDescriptor__xrefs", curie=PHENOPACKETS.curie('xrefs'), - model_uri=PHENOPACKETS.variationDescriptor__xrefs, domain=None, range=Optional[Union[str, list[str]]]) - -slots.vcfRecord__alt = Slot(uri=PHENOPACKETS.alt, name="vcfRecord__alt", curie=PHENOPACKETS.curie('alt'), - model_uri=PHENOPACKETS.vcfRecord__alt, domain=None, range=Optional[str]) - -slots.vcfRecord__chrom = Slot(uri=PHENOPACKETS.chrom, name="vcfRecord__chrom", curie=PHENOPACKETS.curie('chrom'), - model_uri=PHENOPACKETS.vcfRecord__chrom, domain=None, range=Optional[str]) - -slots.vcfRecord__filter = Slot(uri=PHENOPACKETS.filter, name="vcfRecord__filter", curie=PHENOPACKETS.curie('filter'), - model_uri=PHENOPACKETS.vcfRecord__filter, domain=None, range=Optional[str]) - -slots.vcfRecord__genomeAssembly = Slot(uri=PHENOPACKETS.genomeAssembly, name="vcfRecord__genomeAssembly", curie=PHENOPACKETS.curie('genomeAssembly'), - model_uri=PHENOPACKETS.vcfRecord__genomeAssembly, domain=None, range=Optional[str]) - -slots.vcfRecord__id = Slot(uri=PHENOPACKETS.id, name="vcfRecord__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.vcfRecord__id, domain=None, range=Optional[str]) - -slots.vcfRecord__info = Slot(uri=PHENOPACKETS.info, name="vcfRecord__info", curie=PHENOPACKETS.curie('info'), - model_uri=PHENOPACKETS.vcfRecord__info, domain=None, range=Optional[str]) - -slots.vcfRecord__pos = Slot(uri=PHENOPACKETS.pos, name="vcfRecord__pos", curie=PHENOPACKETS.curie('pos'), - model_uri=PHENOPACKETS.vcfRecord__pos, domain=None, range=Optional[int]) - -slots.vcfRecord__qual = Slot(uri=PHENOPACKETS.qual, name="vcfRecord__qual", curie=PHENOPACKETS.curie('qual'), - model_uri=PHENOPACKETS.vcfRecord__qual, domain=None, range=Optional[str]) - -slots.vcfRecord__ref = Slot(uri=PHENOPACKETS.ref, name="vcfRecord__ref", curie=PHENOPACKETS.curie('ref'), - model_uri=PHENOPACKETS.vcfRecord__ref, domain=None, range=Optional[str]) - -slots.any__typeUrl = Slot(uri=PHENOPACKETS.typeUrl, name="any__typeUrl", curie=PHENOPACKETS.curie('typeUrl'), - model_uri=PHENOPACKETS.any__typeUrl, domain=None, range=Optional[str]) - -slots.any__value = Slot(uri=PHENOPACKETS.value, name="any__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.any__value, domain=None, range=Optional[str]) - -slots.abundance__copyNumber = Slot(uri=PHENOPACKETS.copyNumber, name="abundance__copyNumber", curie=PHENOPACKETS.curie('copyNumber'), - model_uri=PHENOPACKETS.abundance__copyNumber, domain=None, range=Optional[Union[dict, CopyNumber]]) - -slots.allele__chromosomeLocation = Slot(uri=PHENOPACKETS.chromosomeLocation, name="allele__chromosomeLocation", curie=PHENOPACKETS.curie('chromosomeLocation'), - model_uri=PHENOPACKETS.allele__chromosomeLocation, domain=None, range=Optional[Union[dict, ChromosomeLocation]]) - -slots.allele__curie = Slot(uri=PHENOPACKETS.curie, name="allele__curie", curie=PHENOPACKETS.curie('curie'), - model_uri=PHENOPACKETS.allele__curie, domain=None, range=Optional[str]) - -slots.allele__derivedSequenceExpression = Slot(uri=PHENOPACKETS.derivedSequenceExpression, name="allele__derivedSequenceExpression", curie=PHENOPACKETS.curie('derivedSequenceExpression'), - model_uri=PHENOPACKETS.allele__derivedSequenceExpression, domain=None, range=Optional[Union[dict, DerivedSequenceExpression]]) - -slots.allele__id = Slot(uri=PHENOPACKETS.id, name="allele__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.allele__id, domain=None, range=Optional[str]) - -slots.allele__literalSequenceExpression = Slot(uri=PHENOPACKETS.literalSequenceExpression, name="allele__literalSequenceExpression", curie=PHENOPACKETS.curie('literalSequenceExpression'), - model_uri=PHENOPACKETS.allele__literalSequenceExpression, domain=None, range=Optional[Union[dict, LiteralSequenceExpression]]) - -slots.allele__repeatedSequenceExpression = Slot(uri=PHENOPACKETS.repeatedSequenceExpression, name="allele__repeatedSequenceExpression", curie=PHENOPACKETS.curie('repeatedSequenceExpression'), - model_uri=PHENOPACKETS.allele__repeatedSequenceExpression, domain=None, range=Optional[Union[dict, RepeatedSequenceExpression]]) - -slots.allele__sequenceLocation = Slot(uri=PHENOPACKETS.sequenceLocation, name="allele__sequenceLocation", curie=PHENOPACKETS.curie('sequenceLocation'), - model_uri=PHENOPACKETS.allele__sequenceLocation, domain=None, range=Optional[Union[dict, SequenceLocation]]) - -slots.chromosomeLocation__chr = Slot(uri=PHENOPACKETS.chr, name="chromosomeLocation__chr", curie=PHENOPACKETS.curie('chr'), - model_uri=PHENOPACKETS.chromosomeLocation__chr, domain=None, range=Optional[str]) - -slots.chromosomeLocation__id = Slot(uri=PHENOPACKETS.id, name="chromosomeLocation__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.chromosomeLocation__id, domain=None, range=Optional[str]) - -slots.chromosomeLocation__interval = Slot(uri=PHENOPACKETS.interval, name="chromosomeLocation__interval", curie=PHENOPACKETS.curie('interval'), - model_uri=PHENOPACKETS.chromosomeLocation__interval, domain=None, range=Optional[Union[dict, CytobandInterval]]) - -slots.chromosomeLocation__speciesId = Slot(uri=PHENOPACKETS.speciesId, name="chromosomeLocation__speciesId", curie=PHENOPACKETS.curie('speciesId'), - model_uri=PHENOPACKETS.chromosomeLocation__speciesId, domain=None, range=Optional[str]) - -slots.copyNumber__allele = Slot(uri=PHENOPACKETS.allele, name="copyNumber__allele", curie=PHENOPACKETS.curie('allele'), - model_uri=PHENOPACKETS.copyNumber__allele, domain=None, range=Optional[Union[dict, Allele]]) - -slots.copyNumber__curie = Slot(uri=PHENOPACKETS.curie, name="copyNumber__curie", curie=PHENOPACKETS.curie('curie'), - model_uri=PHENOPACKETS.copyNumber__curie, domain=None, range=Optional[str]) - -slots.copyNumber__definiteRange = Slot(uri=PHENOPACKETS.definiteRange, name="copyNumber__definiteRange", curie=PHENOPACKETS.curie('definiteRange'), - model_uri=PHENOPACKETS.copyNumber__definiteRange, domain=None, range=Optional[Union[dict, DefiniteRange]]) - -slots.copyNumber__derivedSequenceExpression = Slot(uri=PHENOPACKETS.derivedSequenceExpression, name="copyNumber__derivedSequenceExpression", curie=PHENOPACKETS.curie('derivedSequenceExpression'), - model_uri=PHENOPACKETS.copyNumber__derivedSequenceExpression, domain=None, range=Optional[Union[dict, DerivedSequenceExpression]]) - -slots.copyNumber__gene = Slot(uri=PHENOPACKETS.gene, name="copyNumber__gene", curie=PHENOPACKETS.curie('gene'), - model_uri=PHENOPACKETS.copyNumber__gene, domain=None, range=Optional[Union[dict, Gene]]) - -slots.copyNumber__haplotype = Slot(uri=PHENOPACKETS.haplotype, name="copyNumber__haplotype", curie=PHENOPACKETS.curie('haplotype'), - model_uri=PHENOPACKETS.copyNumber__haplotype, domain=None, range=Optional[Union[dict, Haplotype]]) - -slots.copyNumber__id = Slot(uri=PHENOPACKETS.id, name="copyNumber__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.copyNumber__id, domain=None, range=Optional[str]) - -slots.copyNumber__indefiniteRange = Slot(uri=PHENOPACKETS.indefiniteRange, name="copyNumber__indefiniteRange", curie=PHENOPACKETS.curie('indefiniteRange'), - model_uri=PHENOPACKETS.copyNumber__indefiniteRange, domain=None, range=Optional[Union[dict, IndefiniteRange]]) - -slots.copyNumber__literalSequenceExpression = Slot(uri=PHENOPACKETS.literalSequenceExpression, name="copyNumber__literalSequenceExpression", curie=PHENOPACKETS.curie('literalSequenceExpression'), - model_uri=PHENOPACKETS.copyNumber__literalSequenceExpression, domain=None, range=Optional[Union[dict, LiteralSequenceExpression]]) - -slots.copyNumber__number = Slot(uri=PHENOPACKETS.number, name="copyNumber__number", curie=PHENOPACKETS.curie('number'), - model_uri=PHENOPACKETS.copyNumber__number, domain=None, range=Optional[Union[dict, Number]]) - -slots.copyNumber__repeatedSequenceExpression = Slot(uri=PHENOPACKETS.repeatedSequenceExpression, name="copyNumber__repeatedSequenceExpression", curie=PHENOPACKETS.curie('repeatedSequenceExpression'), - model_uri=PHENOPACKETS.copyNumber__repeatedSequenceExpression, domain=None, range=Optional[Union[dict, RepeatedSequenceExpression]]) - -slots.cytobandInterval__end = Slot(uri=PHENOPACKETS.end, name="cytobandInterval__end", curie=PHENOPACKETS.curie('end'), - model_uri=PHENOPACKETS.cytobandInterval__end, domain=None, range=Optional[str]) - -slots.cytobandInterval__start = Slot(uri=PHENOPACKETS.start, name="cytobandInterval__start", curie=PHENOPACKETS.curie('start'), - model_uri=PHENOPACKETS.cytobandInterval__start, domain=None, range=Optional[str]) - -slots.definiteRange__max = Slot(uri=PHENOPACKETS.max, name="definiteRange__max", curie=PHENOPACKETS.curie('max'), - model_uri=PHENOPACKETS.definiteRange__max, domain=None, range=Optional[int]) - -slots.definiteRange__min = Slot(uri=PHENOPACKETS.min, name="definiteRange__min", curie=PHENOPACKETS.curie('min'), - model_uri=PHENOPACKETS.definiteRange__min, domain=None, range=Optional[int]) - -slots.derivedSequenceExpression__location = Slot(uri=PHENOPACKETS.location, name="derivedSequenceExpression__location", curie=PHENOPACKETS.curie('location'), - model_uri=PHENOPACKETS.derivedSequenceExpression__location, domain=None, range=Optional[Union[dict, SequenceLocation]]) - -slots.derivedSequenceExpression__reverseComplement = Slot(uri=PHENOPACKETS.reverseComplement, name="derivedSequenceExpression__reverseComplement", curie=PHENOPACKETS.curie('reverseComplement'), - model_uri=PHENOPACKETS.derivedSequenceExpression__reverseComplement, domain=None, range=Optional[Union[bool, Bool]]) - -slots.feature__gene = Slot(uri=PHENOPACKETS.gene, name="feature__gene", curie=PHENOPACKETS.curie('gene'), - model_uri=PHENOPACKETS.feature__gene, domain=None, range=Optional[Union[dict, Gene]]) - -slots.gene__geneId = Slot(uri=PHENOPACKETS.geneId, name="gene__geneId", curie=PHENOPACKETS.curie('geneId'), - model_uri=PHENOPACKETS.gene__geneId, domain=None, range=Optional[str]) - -slots.indefiniteRange__comparator = Slot(uri=PHENOPACKETS.comparator, name="indefiniteRange__comparator", curie=PHENOPACKETS.curie('comparator'), - model_uri=PHENOPACKETS.indefiniteRange__comparator, domain=None, range=Optional[str]) - -slots.indefiniteRange__value = Slot(uri=PHENOPACKETS.value, name="indefiniteRange__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.indefiniteRange__value, domain=None, range=Optional[int]) - -slots.literalSequenceExpression__sequence = Slot(uri=PHENOPACKETS.sequence, name="literalSequenceExpression__sequence", curie=PHENOPACKETS.curie('sequence'), - model_uri=PHENOPACKETS.literalSequenceExpression__sequence, domain=None, range=Optional[str]) - -slots.location__chromosomeLocation = Slot(uri=PHENOPACKETS.chromosomeLocation, name="location__chromosomeLocation", curie=PHENOPACKETS.curie('chromosomeLocation'), - model_uri=PHENOPACKETS.location__chromosomeLocation, domain=None, range=Optional[Union[dict, ChromosomeLocation]]) - -slots.location__sequenceLocation = Slot(uri=PHENOPACKETS.sequenceLocation, name="location__sequenceLocation", curie=PHENOPACKETS.curie('sequenceLocation'), - model_uri=PHENOPACKETS.location__sequenceLocation, domain=None, range=Optional[Union[dict, SequenceLocation]]) - -slots.member__allele = Slot(uri=PHENOPACKETS.allele, name="member__allele", curie=PHENOPACKETS.curie('allele'), - model_uri=PHENOPACKETS.member__allele, domain=None, range=Optional[Union[dict, Allele]]) - -slots.member__copyNumber = Slot(uri=PHENOPACKETS.copyNumber, name="member__copyNumber", curie=PHENOPACKETS.curie('copyNumber'), - model_uri=PHENOPACKETS.member__copyNumber, domain=None, range=Optional[Union[dict, CopyNumber]]) - -slots.member__curie = Slot(uri=PHENOPACKETS.curie, name="member__curie", curie=PHENOPACKETS.curie('curie'), - model_uri=PHENOPACKETS.member__curie, domain=None, range=Optional[str]) - -slots.member__haplotype = Slot(uri=PHENOPACKETS.haplotype, name="member__haplotype", curie=PHENOPACKETS.curie('haplotype'), - model_uri=PHENOPACKETS.member__haplotype, domain=None, range=Optional[Union[dict, Haplotype]]) - -slots.member__id = Slot(uri=PHENOPACKETS.id, name="member__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.member__id, domain=None, range=Optional[str]) - -slots.member__members = Slot(uri=PHENOPACKETS.members, name="member__members", curie=PHENOPACKETS.curie('members'), - model_uri=PHENOPACKETS.member__members, domain=None, range=Optional[Union[Union[dict, Member], list[Union[dict, Member]]]]) - -slots.member__text = Slot(uri=PHENOPACKETS.text, name="member__text", curie=PHENOPACKETS.curie('text'), - model_uri=PHENOPACKETS.member__text, domain=None, range=Optional[Union[dict, Text]]) - -slots.member__variationSet = Slot(uri=PHENOPACKETS.variationSet, name="member__variationSet", curie=PHENOPACKETS.curie('variationSet'), - model_uri=PHENOPACKETS.member__variationSet, domain=None, range=Optional[Union[dict, VariationSet]]) - -slots.molecularVariation__allele = Slot(uri=PHENOPACKETS.allele, name="molecularVariation__allele", curie=PHENOPACKETS.curie('allele'), - model_uri=PHENOPACKETS.molecularVariation__allele, domain=None, range=Optional[Union[dict, Allele]]) - -slots.molecularVariation__haplotype = Slot(uri=PHENOPACKETS.haplotype, name="molecularVariation__haplotype", curie=PHENOPACKETS.curie('haplotype'), - model_uri=PHENOPACKETS.molecularVariation__haplotype, domain=None, range=Optional[Union[dict, Haplotype]]) - -slots.number__value = Slot(uri=PHENOPACKETS.value, name="number__value", curie=PHENOPACKETS.curie('value'), - model_uri=PHENOPACKETS.number__value, domain=None, range=Optional[int]) - -slots.repeatedSequenceExpression__definiteRange = Slot(uri=PHENOPACKETS.definiteRange, name="repeatedSequenceExpression__definiteRange", curie=PHENOPACKETS.curie('definiteRange'), - model_uri=PHENOPACKETS.repeatedSequenceExpression__definiteRange, domain=None, range=Optional[Union[dict, DefiniteRange]]) - -slots.repeatedSequenceExpression__derivedSequenceExpression = Slot(uri=PHENOPACKETS.derivedSequenceExpression, name="repeatedSequenceExpression__derivedSequenceExpression", curie=PHENOPACKETS.curie('derivedSequenceExpression'), - model_uri=PHENOPACKETS.repeatedSequenceExpression__derivedSequenceExpression, domain=None, range=Optional[Union[dict, DerivedSequenceExpression]]) - -slots.repeatedSequenceExpression__indefiniteRange = Slot(uri=PHENOPACKETS.indefiniteRange, name="repeatedSequenceExpression__indefiniteRange", curie=PHENOPACKETS.curie('indefiniteRange'), - model_uri=PHENOPACKETS.repeatedSequenceExpression__indefiniteRange, domain=None, range=Optional[Union[dict, IndefiniteRange]]) - -slots.repeatedSequenceExpression__literalSequenceExpression = Slot(uri=PHENOPACKETS.literalSequenceExpression, name="repeatedSequenceExpression__literalSequenceExpression", curie=PHENOPACKETS.curie('literalSequenceExpression'), - model_uri=PHENOPACKETS.repeatedSequenceExpression__literalSequenceExpression, domain=None, range=Optional[Union[dict, LiteralSequenceExpression]]) - -slots.repeatedSequenceExpression__number = Slot(uri=PHENOPACKETS.number, name="repeatedSequenceExpression__number", curie=PHENOPACKETS.curie('number'), - model_uri=PHENOPACKETS.repeatedSequenceExpression__number, domain=None, range=Optional[Union[dict, Number]]) - -slots.sequenceExpression__derivedSequenceExpression = Slot(uri=PHENOPACKETS.derivedSequenceExpression, name="sequenceExpression__derivedSequenceExpression", curie=PHENOPACKETS.curie('derivedSequenceExpression'), - model_uri=PHENOPACKETS.sequenceExpression__derivedSequenceExpression, domain=None, range=Optional[Union[dict, DerivedSequenceExpression]]) - -slots.sequenceExpression__literalSequenceExpression = Slot(uri=PHENOPACKETS.literalSequenceExpression, name="sequenceExpression__literalSequenceExpression", curie=PHENOPACKETS.curie('literalSequenceExpression'), - model_uri=PHENOPACKETS.sequenceExpression__literalSequenceExpression, domain=None, range=Optional[Union[dict, LiteralSequenceExpression]]) - -slots.sequenceExpression__repeatedSequenceExpression = Slot(uri=PHENOPACKETS.repeatedSequenceExpression, name="sequenceExpression__repeatedSequenceExpression", curie=PHENOPACKETS.curie('repeatedSequenceExpression'), - model_uri=PHENOPACKETS.sequenceExpression__repeatedSequenceExpression, domain=None, range=Optional[Union[dict, RepeatedSequenceExpression]]) - -slots.sequenceInterval__endDefiniteRange = Slot(uri=PHENOPACKETS.endDefiniteRange, name="sequenceInterval__endDefiniteRange", curie=PHENOPACKETS.curie('endDefiniteRange'), - model_uri=PHENOPACKETS.sequenceInterval__endDefiniteRange, domain=None, range=Optional[Union[dict, DefiniteRange]]) - -slots.sequenceInterval__endIndefiniteRange = Slot(uri=PHENOPACKETS.endIndefiniteRange, name="sequenceInterval__endIndefiniteRange", curie=PHENOPACKETS.curie('endIndefiniteRange'), - model_uri=PHENOPACKETS.sequenceInterval__endIndefiniteRange, domain=None, range=Optional[Union[dict, IndefiniteRange]]) - -slots.sequenceInterval__endNumber = Slot(uri=PHENOPACKETS.endNumber, name="sequenceInterval__endNumber", curie=PHENOPACKETS.curie('endNumber'), - model_uri=PHENOPACKETS.sequenceInterval__endNumber, domain=None, range=Optional[Union[dict, Number]]) - -slots.sequenceInterval__startDefiniteRange = Slot(uri=PHENOPACKETS.startDefiniteRange, name="sequenceInterval__startDefiniteRange", curie=PHENOPACKETS.curie('startDefiniteRange'), - model_uri=PHENOPACKETS.sequenceInterval__startDefiniteRange, domain=None, range=Optional[Union[dict, DefiniteRange]]) - -slots.sequenceInterval__startIndefiniteRange = Slot(uri=PHENOPACKETS.startIndefiniteRange, name="sequenceInterval__startIndefiniteRange", curie=PHENOPACKETS.curie('startIndefiniteRange'), - model_uri=PHENOPACKETS.sequenceInterval__startIndefiniteRange, domain=None, range=Optional[Union[dict, IndefiniteRange]]) - -slots.sequenceInterval__startNumber = Slot(uri=PHENOPACKETS.startNumber, name="sequenceInterval__startNumber", curie=PHENOPACKETS.curie('startNumber'), - model_uri=PHENOPACKETS.sequenceInterval__startNumber, domain=None, range=Optional[Union[dict, Number]]) - -slots.sequenceLocation__id = Slot(uri=PHENOPACKETS.id, name="sequenceLocation__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.sequenceLocation__id, domain=None, range=Optional[str]) - -slots.sequenceLocation__sequenceId = Slot(uri=PHENOPACKETS.sequenceId, name="sequenceLocation__sequenceId", curie=PHENOPACKETS.curie('sequenceId'), - model_uri=PHENOPACKETS.sequenceLocation__sequenceId, domain=None, range=Optional[str]) - -slots.sequenceLocation__sequenceInterval = Slot(uri=PHENOPACKETS.sequenceInterval, name="sequenceLocation__sequenceInterval", curie=PHENOPACKETS.curie('sequenceInterval'), - model_uri=PHENOPACKETS.sequenceLocation__sequenceInterval, domain=None, range=Optional[Union[dict, SequenceInterval]]) - -slots.sequenceState__sequence = Slot(uri=PHENOPACKETS.sequence, name="sequenceState__sequence", curie=PHENOPACKETS.curie('sequence'), - model_uri=PHENOPACKETS.sequenceState__sequence, domain=None, range=Optional[str]) - -slots.simpleInterval__end = Slot(uri=PHENOPACKETS.end, name="simpleInterval__end", curie=PHENOPACKETS.curie('end'), - model_uri=PHENOPACKETS.simpleInterval__end, domain=None, range=Optional[int]) - -slots.simpleInterval__start = Slot(uri=PHENOPACKETS.start, name="simpleInterval__start", curie=PHENOPACKETS.curie('start'), - model_uri=PHENOPACKETS.simpleInterval__start, domain=None, range=Optional[int]) - -slots.systemicVariation__copyNumber = Slot(uri=PHENOPACKETS.copyNumber, name="systemicVariation__copyNumber", curie=PHENOPACKETS.curie('copyNumber'), - model_uri=PHENOPACKETS.systemicVariation__copyNumber, domain=None, range=Optional[Union[dict, CopyNumber]]) - -slots.text__definition = Slot(uri=PHENOPACKETS.definition, name="text__definition", curie=PHENOPACKETS.curie('definition'), - model_uri=PHENOPACKETS.text__definition, domain=None, range=Optional[str]) - -slots.text__id = Slot(uri=PHENOPACKETS.id, name="text__id", curie=PHENOPACKETS.curie('id'), - model_uri=PHENOPACKETS.text__id, domain=None, range=Optional[str]) - -slots.utilityVariation__text = Slot(uri=PHENOPACKETS.text, name="utilityVariation__text", curie=PHENOPACKETS.curie('text'), - model_uri=PHENOPACKETS.utilityVariation__text, domain=None, range=Optional[Union[dict, Text]]) - -slots.utilityVariation__variationSet = Slot(uri=PHENOPACKETS.variationSet, name="utilityVariation__variationSet", curie=PHENOPACKETS.curie('variationSet'), - model_uri=PHENOPACKETS.utilityVariation__variationSet, domain=None, range=Optional[Union[dict, VariationSet]]) - -slots.variation__allele = Slot(uri=PHENOPACKETS.allele, name="variation__allele", curie=PHENOPACKETS.curie('allele'), - model_uri=PHENOPACKETS.variation__allele, domain=None, range=Optional[Union[dict, Allele]]) - -slots.variation__copyNumber = Slot(uri=PHENOPACKETS.copyNumber, name="variation__copyNumber", curie=PHENOPACKETS.curie('copyNumber'), - model_uri=PHENOPACKETS.variation__copyNumber, domain=None, range=Optional[Union[dict, CopyNumber]]) - -slots.variation__haplotype = Slot(uri=PHENOPACKETS.haplotype, name="variation__haplotype", curie=PHENOPACKETS.curie('haplotype'), - model_uri=PHENOPACKETS.variation__haplotype, domain=None, range=Optional[Union[dict, Haplotype]]) - -slots.variation__text = Slot(uri=PHENOPACKETS.text, name="variation__text", curie=PHENOPACKETS.curie('text'), - model_uri=PHENOPACKETS.variation__text, domain=None, range=Optional[Union[dict, Text]]) -slots.variation__variationSet = Slot(uri=PHENOPACKETS.variationSet, name="variation__variationSet", curie=PHENOPACKETS.curie('variationSet'), - model_uri=PHENOPACKETS.variation__variationSet, domain=None, range=Optional[Union[dict, VariationSet]]) +slots.cohort__description = Slot( + uri=PHENOPACKETS.description, + name="cohort__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.cohort__description, + domain=None, + range=Optional[str], +) + +slots.cohort__files = Slot( + uri=PHENOPACKETS.files, + name="cohort__files", + curie=PHENOPACKETS.curie("files"), + model_uri=PHENOPACKETS.cohort__files, + domain=None, + range=Optional[Union[Union[dict, File], list[Union[dict, File]]]], +) + +slots.cohort__id = Slot( + uri=PHENOPACKETS.id, + name="cohort__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.cohort__id, + domain=None, + range=Optional[str], +) + +slots.cohort__members = Slot( + uri=PHENOPACKETS.members, + name="cohort__members", + curie=PHENOPACKETS.curie("members"), + model_uri=PHENOPACKETS.cohort__members, + domain=None, + range=Optional[Union[Union[dict, Phenopacket], list[Union[dict, Phenopacket]]]], +) + +slots.cohort__metaData = Slot( + uri=PHENOPACKETS.metaData, + name="cohort__metaData", + curie=PHENOPACKETS.curie("metaData"), + model_uri=PHENOPACKETS.cohort__metaData, + domain=None, + range=Union[dict, MetaData], +) + +slots.family__consanguinousParents = Slot( + uri=PHENOPACKETS.consanguinousParents, + name="family__consanguinousParents", + curie=PHENOPACKETS.curie("consanguinousParents"), + model_uri=PHENOPACKETS.family__consanguinousParents, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.family__files = Slot( + uri=PHENOPACKETS.files, + name="family__files", + curie=PHENOPACKETS.curie("files"), + model_uri=PHENOPACKETS.family__files, + domain=None, + range=Optional[Union[Union[dict, File], list[Union[dict, File]]]], +) + +slots.family__id = Slot( + uri=PHENOPACKETS.id, + name="family__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.family__id, + domain=None, + range=Optional[str], +) + +slots.family__metaData = Slot( + uri=PHENOPACKETS.metaData, + name="family__metaData", + curie=PHENOPACKETS.curie("metaData"), + model_uri=PHENOPACKETS.family__metaData, + domain=None, + range=Union[dict, MetaData], +) + +slots.family__pedigree = Slot( + uri=PHENOPACKETS.pedigree, + name="family__pedigree", + curie=PHENOPACKETS.curie("pedigree"), + model_uri=PHENOPACKETS.family__pedigree, + domain=None, + range=Optional[Union[dict, Pedigree]], +) + +slots.family__proband = Slot( + uri=PHENOPACKETS.proband, + name="family__proband", + curie=PHENOPACKETS.curie("proband"), + model_uri=PHENOPACKETS.family__proband, + domain=None, + range=Optional[Union[dict, Phenopacket]], +) + +slots.family__relatives = Slot( + uri=PHENOPACKETS.relatives, + name="family__relatives", + curie=PHENOPACKETS.curie("relatives"), + model_uri=PHENOPACKETS.family__relatives, + domain=None, + range=Optional[Union[Union[dict, Phenopacket], list[Union[dict, Phenopacket]]]], +) + +slots.phenopacket__biosamples = Slot( + uri=PHENOPACKETS.biosamples, + name="phenopacket__biosamples", + curie=PHENOPACKETS.curie("biosamples"), + model_uri=PHENOPACKETS.phenopacket__biosamples, + domain=None, + range=Optional[Union[Union[dict, Biosample], list[Union[dict, Biosample]]]], +) + +slots.phenopacket__diseases = Slot( + uri=PHENOPACKETS.diseases, + name="phenopacket__diseases", + curie=PHENOPACKETS.curie("diseases"), + model_uri=PHENOPACKETS.phenopacket__diseases, + domain=None, + range=Optional[Union[Union[dict, Disease], list[Union[dict, Disease]]]], +) + +slots.phenopacket__files = Slot( + uri=PHENOPACKETS.files, + name="phenopacket__files", + curie=PHENOPACKETS.curie("files"), + model_uri=PHENOPACKETS.phenopacket__files, + domain=None, + range=Optional[Union[Union[dict, File], list[Union[dict, File]]]], +) + +slots.phenopacket__id = Slot( + uri=PHENOPACKETS.id, + name="phenopacket__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.phenopacket__id, + domain=None, + range=Optional[str], +) + +slots.phenopacket__interpretations = Slot( + uri=PHENOPACKETS.interpretations, + name="phenopacket__interpretations", + curie=PHENOPACKETS.curie("interpretations"), + model_uri=PHENOPACKETS.phenopacket__interpretations, + domain=None, + range=Optional[Union[Union[dict, Interpretation], list[Union[dict, Interpretation]]]], +) + +slots.phenopacket__measurements = Slot( + uri=PHENOPACKETS.measurements, + name="phenopacket__measurements", + curie=PHENOPACKETS.curie("measurements"), + model_uri=PHENOPACKETS.phenopacket__measurements, + domain=None, + range=Optional[Union[Union[dict, Measurement], list[Union[dict, Measurement]]]], +) + +slots.phenopacket__medicalActions = Slot( + uri=PHENOPACKETS.medicalActions, + name="phenopacket__medicalActions", + curie=PHENOPACKETS.curie("medicalActions"), + model_uri=PHENOPACKETS.phenopacket__medicalActions, + domain=None, + range=Optional[Union[Union[dict, MedicalAction], list[Union[dict, MedicalAction]]]], +) + +slots.phenopacket__metaData = Slot( + uri=PHENOPACKETS.metaData, + name="phenopacket__metaData", + curie=PHENOPACKETS.curie("metaData"), + model_uri=PHENOPACKETS.phenopacket__metaData, + domain=None, + range=Union[dict, MetaData], +) + +slots.phenopacket__phenotypicFeatures = Slot( + uri=PHENOPACKETS.phenotypicFeatures, + name="phenopacket__phenotypicFeatures", + curie=PHENOPACKETS.curie("phenotypicFeatures"), + model_uri=PHENOPACKETS.phenopacket__phenotypicFeatures, + domain=None, + range=Optional[Union[Union[dict, PhenotypicFeature], list[Union[dict, PhenotypicFeature]]]], +) + +slots.phenopacket__subject = Slot( + uri=PHENOPACKETS.subject, + name="phenopacket__subject", + curie=PHENOPACKETS.curie("subject"), + model_uri=PHENOPACKETS.phenopacket__subject, + domain=None, + range=Optional[Union[dict, Individual]], +) + +slots.age__iso8601duration = Slot( + uri=PHENOPACKETS.iso8601duration, + name="age__iso8601duration", + curie=PHENOPACKETS.curie("iso8601duration"), + model_uri=PHENOPACKETS.age__iso8601duration, + domain=None, + range=Optional[str], +) + +slots.ageRange__end = Slot( + uri=PHENOPACKETS.end, + name="ageRange__end", + curie=PHENOPACKETS.curie("end"), + model_uri=PHENOPACKETS.ageRange__end, + domain=None, + range=Optional[Union[dict, Age]], +) + +slots.ageRange__start = Slot( + uri=PHENOPACKETS.start, + name="ageRange__start", + curie=PHENOPACKETS.curie("start"), + model_uri=PHENOPACKETS.ageRange__start, + domain=None, + range=Optional[Union[dict, Age]], +) + +slots.evidence__evidenceCode = Slot( + uri=PHENOPACKETS.evidenceCode, + name="evidence__evidenceCode", + curie=PHENOPACKETS.curie("evidenceCode"), + model_uri=PHENOPACKETS.evidence__evidenceCode, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.evidence__reference = Slot( + uri=PHENOPACKETS.reference, + name="evidence__reference", + curie=PHENOPACKETS.curie("reference"), + model_uri=PHENOPACKETS.evidence__reference, + domain=None, + range=Optional[Union[dict, ExternalReference]], +) + +slots.externalReference__description = Slot( + uri=PHENOPACKETS.description, + name="externalReference__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.externalReference__description, + domain=None, + range=Optional[str], +) + +slots.externalReference__id = Slot( + uri=PHENOPACKETS.id, + name="externalReference__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.externalReference__id, + domain=None, + range=Optional[str], +) + +slots.externalReference__reference = Slot( + uri=PHENOPACKETS.reference, + name="externalReference__reference", + curie=PHENOPACKETS.curie("reference"), + model_uri=PHENOPACKETS.externalReference__reference, + domain=None, + range=Optional[str], +) + +slots.file__fileAttributes = Slot( + uri=PHENOPACKETS.fileAttributes, + name="file__fileAttributes", + curie=PHENOPACKETS.curie("fileAttributes"), + model_uri=PHENOPACKETS.file__fileAttributes, + domain=None, + range=Optional[Union[dict, Dictionary]], +) + +slots.file__individualToFileIdentifiers = Slot( + uri=PHENOPACKETS.individualToFileIdentifiers, + name="file__individualToFileIdentifiers", + curie=PHENOPACKETS.curie("individualToFileIdentifiers"), + model_uri=PHENOPACKETS.file__individualToFileIdentifiers, + domain=None, + range=Optional[Union[dict, Dictionary]], +) + +slots.file__uri = Slot( + uri=PHENOPACKETS.uri, + name="file__uri", + curie=PHENOPACKETS.curie("uri"), + model_uri=PHENOPACKETS.file__uri, + domain=None, + range=Optional[str], +) + +slots.gestationalAge__days = Slot( + uri=PHENOPACKETS.days, + name="gestationalAge__days", + curie=PHENOPACKETS.curie("days"), + model_uri=PHENOPACKETS.gestationalAge__days, + domain=None, + range=Optional[int], +) + +slots.gestationalAge__weeks = Slot( + uri=PHENOPACKETS.weeks, + name="gestationalAge__weeks", + curie=PHENOPACKETS.curie("weeks"), + model_uri=PHENOPACKETS.gestationalAge__weeks, + domain=None, + range=Optional[int], +) + +slots.ontologyClass__id = Slot( + uri=PHENOPACKETS.id, + name="ontologyClass__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.ontologyClass__id, + domain=None, + range=URIRef, +) + +slots.ontologyClass__label = Slot( + uri=PHENOPACKETS.label, + name="ontologyClass__label", + curie=PHENOPACKETS.curie("label"), + model_uri=PHENOPACKETS.ontologyClass__label, + domain=None, + range=Optional[str], +) + +slots.procedure__bodySite = Slot( + uri=PHENOPACKETS.bodySite, + name="procedure__bodySite", + curie=PHENOPACKETS.curie("bodySite"), + model_uri=PHENOPACKETS.procedure__bodySite, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.procedure__code = Slot( + uri=PHENOPACKETS.code, + name="procedure__code", + curie=PHENOPACKETS.curie("code"), + model_uri=PHENOPACKETS.procedure__code, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.procedure__performed = Slot( + uri=PHENOPACKETS.performed, + name="procedure__performed", + curie=PHENOPACKETS.curie("performed"), + model_uri=PHENOPACKETS.procedure__performed, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.timeElement__age = Slot( + uri=PHENOPACKETS.age, + name="timeElement__age", + curie=PHENOPACKETS.curie("age"), + model_uri=PHENOPACKETS.timeElement__age, + domain=None, + range=Optional[Union[dict, Age]], +) + +slots.timeElement__ageRange = Slot( + uri=PHENOPACKETS.ageRange, + name="timeElement__ageRange", + curie=PHENOPACKETS.curie("ageRange"), + model_uri=PHENOPACKETS.timeElement__ageRange, + domain=None, + range=Optional[Union[dict, AgeRange]], +) + +slots.timeElement__gestationalAge = Slot( + uri=PHENOPACKETS.gestationalAge, + name="timeElement__gestationalAge", + curie=PHENOPACKETS.curie("gestationalAge"), + model_uri=PHENOPACKETS.timeElement__gestationalAge, + domain=None, + range=Optional[Union[dict, GestationalAge]], +) + +slots.timeElement__interval = Slot( + uri=PHENOPACKETS.interval, + name="timeElement__interval", + curie=PHENOPACKETS.curie("interval"), + model_uri=PHENOPACKETS.timeElement__interval, + domain=None, + range=Optional[Union[dict, TimeInterval]], +) + +slots.timeElement__ontologyClass = Slot( + uri=PHENOPACKETS.ontologyClass, + name="timeElement__ontologyClass", + curie=PHENOPACKETS.curie("ontologyClass"), + model_uri=PHENOPACKETS.timeElement__ontologyClass, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.timeElement__timestamp = Slot( + uri=PHENOPACKETS.timestamp, + name="timeElement__timestamp", + curie=PHENOPACKETS.curie("timestamp"), + model_uri=PHENOPACKETS.timeElement__timestamp, + domain=None, + range=Optional[str], +) + +slots.timeInterval__end = Slot( + uri=PHENOPACKETS.end, + name="timeInterval__end", + curie=PHENOPACKETS.curie("end"), + model_uri=PHENOPACKETS.timeInterval__end, + domain=None, + range=Optional[str], +) + +slots.timeInterval__start = Slot( + uri=PHENOPACKETS.start, + name="timeInterval__start", + curie=PHENOPACKETS.curie("start"), + model_uri=PHENOPACKETS.timeInterval__start, + domain=None, + range=Optional[str], +) + +slots.biosample__derivedFromId = Slot( + uri=PHENOPACKETS.derivedFromId, + name="biosample__derivedFromId", + curie=PHENOPACKETS.curie("derivedFromId"), + model_uri=PHENOPACKETS.biosample__derivedFromId, + domain=None, + range=Optional[str], +) + +slots.biosample__description = Slot( + uri=PHENOPACKETS.description, + name="biosample__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.biosample__description, + domain=None, + range=Optional[str], +) + +slots.biosample__diagnosticMarkers = Slot( + uri=PHENOPACKETS.diagnosticMarkers, + name="biosample__diagnosticMarkers", + curie=PHENOPACKETS.curie("diagnosticMarkers"), + model_uri=PHENOPACKETS.biosample__diagnosticMarkers, + domain=None, + range=Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ], +) + +slots.biosample__files = Slot( + uri=PHENOPACKETS.files, + name="biosample__files", + curie=PHENOPACKETS.curie("files"), + model_uri=PHENOPACKETS.biosample__files, + domain=None, + range=Optional[Union[Union[dict, File], list[Union[dict, File]]]], +) + +slots.biosample__histologicalDiagnosis = Slot( + uri=PHENOPACKETS.histologicalDiagnosis, + name="biosample__histologicalDiagnosis", + curie=PHENOPACKETS.curie("histologicalDiagnosis"), + model_uri=PHENOPACKETS.biosample__histologicalDiagnosis, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__id = Slot( + uri=PHENOPACKETS.id, + name="biosample__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.biosample__id, + domain=None, + range=Optional[str], +) + +slots.biosample__individualId = Slot( + uri=PHENOPACKETS.individualId, + name="biosample__individualId", + curie=PHENOPACKETS.curie("individualId"), + model_uri=PHENOPACKETS.biosample__individualId, + domain=None, + range=Optional[str], +) + +slots.biosample__materialSample = Slot( + uri=PHENOPACKETS.materialSample, + name="biosample__materialSample", + curie=PHENOPACKETS.curie("materialSample"), + model_uri=PHENOPACKETS.biosample__materialSample, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__measurements = Slot( + uri=PHENOPACKETS.measurements, + name="biosample__measurements", + curie=PHENOPACKETS.curie("measurements"), + model_uri=PHENOPACKETS.biosample__measurements, + domain=None, + range=Optional[Union[Union[dict, Measurement], list[Union[dict, Measurement]]]], +) + +slots.biosample__pathologicalStage = Slot( + uri=PHENOPACKETS.pathologicalStage, + name="biosample__pathologicalStage", + curie=PHENOPACKETS.curie("pathologicalStage"), + model_uri=PHENOPACKETS.biosample__pathologicalStage, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__pathologicalTnmFinding = Slot( + uri=PHENOPACKETS.pathologicalTnmFinding, + name="biosample__pathologicalTnmFinding", + curie=PHENOPACKETS.curie("pathologicalTnmFinding"), + model_uri=PHENOPACKETS.biosample__pathologicalTnmFinding, + domain=None, + range=Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ], +) + +slots.biosample__phenotypicFeatures = Slot( + uri=PHENOPACKETS.phenotypicFeatures, + name="biosample__phenotypicFeatures", + curie=PHENOPACKETS.curie("phenotypicFeatures"), + model_uri=PHENOPACKETS.biosample__phenotypicFeatures, + domain=None, + range=Optional[Union[Union[dict, PhenotypicFeature], list[Union[dict, PhenotypicFeature]]]], +) + +slots.biosample__procedure = Slot( + uri=PHENOPACKETS.procedure, + name="biosample__procedure", + curie=PHENOPACKETS.curie("procedure"), + model_uri=PHENOPACKETS.biosample__procedure, + domain=None, + range=Optional[Union[dict, Procedure]], +) + +slots.biosample__sampleProcessing = Slot( + uri=PHENOPACKETS.sampleProcessing, + name="biosample__sampleProcessing", + curie=PHENOPACKETS.curie("sampleProcessing"), + model_uri=PHENOPACKETS.biosample__sampleProcessing, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__sampleStorage = Slot( + uri=PHENOPACKETS.sampleStorage, + name="biosample__sampleStorage", + curie=PHENOPACKETS.curie("sampleStorage"), + model_uri=PHENOPACKETS.biosample__sampleStorage, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__sampleType = Slot( + uri=PHENOPACKETS.sampleType, + name="biosample__sampleType", + curie=PHENOPACKETS.curie("sampleType"), + model_uri=PHENOPACKETS.biosample__sampleType, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__sampledTissue = Slot( + uri=PHENOPACKETS.sampledTissue, + name="biosample__sampledTissue", + curie=PHENOPACKETS.curie("sampledTissue"), + model_uri=PHENOPACKETS.biosample__sampledTissue, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__taxonomy = Slot( + uri=PHENOPACKETS.taxonomy, + name="biosample__taxonomy", + curie=PHENOPACKETS.curie("taxonomy"), + model_uri=PHENOPACKETS.biosample__taxonomy, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__timeOfCollection = Slot( + uri=PHENOPACKETS.timeOfCollection, + name="biosample__timeOfCollection", + curie=PHENOPACKETS.curie("timeOfCollection"), + model_uri=PHENOPACKETS.biosample__timeOfCollection, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.biosample__tumorGrade = Slot( + uri=PHENOPACKETS.tumorGrade, + name="biosample__tumorGrade", + curie=PHENOPACKETS.curie("tumorGrade"), + model_uri=PHENOPACKETS.biosample__tumorGrade, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.biosample__tumorProgression = Slot( + uri=PHENOPACKETS.tumorProgression, + name="biosample__tumorProgression", + curie=PHENOPACKETS.curie("tumorProgression"), + model_uri=PHENOPACKETS.biosample__tumorProgression, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.disease__clinicalTnmFinding = Slot( + uri=PHENOPACKETS.clinicalTnmFinding, + name="disease__clinicalTnmFinding", + curie=PHENOPACKETS.curie("clinicalTnmFinding"), + model_uri=PHENOPACKETS.disease__clinicalTnmFinding, + domain=None, + range=Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ], +) + +slots.disease__diseaseStage = Slot( + uri=PHENOPACKETS.diseaseStage, + name="disease__diseaseStage", + curie=PHENOPACKETS.curie("diseaseStage"), + model_uri=PHENOPACKETS.disease__diseaseStage, + domain=None, + range=Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ], +) + +slots.disease__excluded = Slot( + uri=PHENOPACKETS.excluded, + name="disease__excluded", + curie=PHENOPACKETS.curie("excluded"), + model_uri=PHENOPACKETS.disease__excluded, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.disease__laterality = Slot( + uri=PHENOPACKETS.laterality, + name="disease__laterality", + curie=PHENOPACKETS.curie("laterality"), + model_uri=PHENOPACKETS.disease__laterality, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.disease__onset = Slot( + uri=PHENOPACKETS.onset, + name="disease__onset", + curie=PHENOPACKETS.curie("onset"), + model_uri=PHENOPACKETS.disease__onset, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.disease__primarySite = Slot( + uri=PHENOPACKETS.primarySite, + name="disease__primarySite", + curie=PHENOPACKETS.curie("primarySite"), + model_uri=PHENOPACKETS.disease__primarySite, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.disease__resolution = Slot( + uri=PHENOPACKETS.resolution, + name="disease__resolution", + curie=PHENOPACKETS.curie("resolution"), + model_uri=PHENOPACKETS.disease__resolution, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.disease__term = Slot( + uri=PHENOPACKETS.term, + name="disease__term", + curie=PHENOPACKETS.curie("term"), + model_uri=PHENOPACKETS.disease__term, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.diagnosis__disease = Slot( + uri=PHENOPACKETS.disease, + name="diagnosis__disease", + curie=PHENOPACKETS.curie("disease"), + model_uri=PHENOPACKETS.diagnosis__disease, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.diagnosis__genomicInterpretations = Slot( + uri=PHENOPACKETS.genomicInterpretations, + name="diagnosis__genomicInterpretations", + curie=PHENOPACKETS.curie("genomicInterpretations"), + model_uri=PHENOPACKETS.diagnosis__genomicInterpretations, + domain=None, + range=Optional[Union[Union[dict, GenomicInterpretation], list[Union[dict, GenomicInterpretation]]]], +) + +slots.genomicInterpretation__gene = Slot( + uri=PHENOPACKETS.gene, + name="genomicInterpretation__gene", + curie=PHENOPACKETS.curie("gene"), + model_uri=PHENOPACKETS.genomicInterpretation__gene, + domain=None, + range=Optional[Union[dict, GeneDescriptor]], +) + +slots.genomicInterpretation__interpretationStatus = Slot( + uri=PHENOPACKETS.interpretationStatus, + name="genomicInterpretation__interpretationStatus", + curie=PHENOPACKETS.curie("interpretationStatus"), + model_uri=PHENOPACKETS.genomicInterpretation__interpretationStatus, + domain=None, + range=Optional[Union[str, "InterpretationStatus"]], +) + +slots.genomicInterpretation__subjectOrBiosampleId = Slot( + uri=PHENOPACKETS.subjectOrBiosampleId, + name="genomicInterpretation__subjectOrBiosampleId", + curie=PHENOPACKETS.curie("subjectOrBiosampleId"), + model_uri=PHENOPACKETS.genomicInterpretation__subjectOrBiosampleId, + domain=None, + range=Optional[str], +) + +slots.genomicInterpretation__variantInterpretation = Slot( + uri=PHENOPACKETS.variantInterpretation, + name="genomicInterpretation__variantInterpretation", + curie=PHENOPACKETS.curie("variantInterpretation"), + model_uri=PHENOPACKETS.genomicInterpretation__variantInterpretation, + domain=None, + range=Optional[Union[dict, VariantInterpretation]], +) + +slots.interpretation__diagnosis = Slot( + uri=PHENOPACKETS.diagnosis, + name="interpretation__diagnosis", + curie=PHENOPACKETS.curie("diagnosis"), + model_uri=PHENOPACKETS.interpretation__diagnosis, + domain=None, + range=Optional[Union[dict, Diagnosis]], +) + +slots.interpretation__id = Slot( + uri=PHENOPACKETS.id, + name="interpretation__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.interpretation__id, + domain=None, + range=Optional[str], +) + +slots.interpretation__progressStatus = Slot( + uri=PHENOPACKETS.progressStatus, + name="interpretation__progressStatus", + curie=PHENOPACKETS.curie("progressStatus"), + model_uri=PHENOPACKETS.interpretation__progressStatus, + domain=None, + range=Optional[Union[str, "ProgressStatus"]], +) + +slots.interpretation__summary = Slot( + uri=PHENOPACKETS.summary, + name="interpretation__summary", + curie=PHENOPACKETS.curie("summary"), + model_uri=PHENOPACKETS.interpretation__summary, + domain=None, + range=Optional[str], +) + +slots.variantInterpretation__acmgPathogenicityClassification = Slot( + uri=PHENOPACKETS.acmgPathogenicityClassification, + name="variantInterpretation__acmgPathogenicityClassification", + curie=PHENOPACKETS.curie("acmgPathogenicityClassification"), + model_uri=PHENOPACKETS.variantInterpretation__acmgPathogenicityClassification, + domain=None, + range=Optional[Union[str, "AcmgPathogenicityClassification"]], +) + +slots.variantInterpretation__therapeuticActionability = Slot( + uri=PHENOPACKETS.therapeuticActionability, + name="variantInterpretation__therapeuticActionability", + curie=PHENOPACKETS.curie("therapeuticActionability"), + model_uri=PHENOPACKETS.variantInterpretation__therapeuticActionability, + domain=None, + range=Optional[Union[str, "TherapeuticActionability"]], +) + +slots.variantInterpretation__variationDescriptor = Slot( + uri=PHENOPACKETS.variationDescriptor, + name="variantInterpretation__variationDescriptor", + curie=PHENOPACKETS.curie("variationDescriptor"), + model_uri=PHENOPACKETS.variantInterpretation__variationDescriptor, + domain=None, + range=Optional[Union[dict, VariationDescriptor]], +) + +slots.individual__alternateIds = Slot( + uri=PHENOPACKETS.alternateIds, + name="individual__alternateIds", + curie=PHENOPACKETS.curie("alternateIds"), + model_uri=PHENOPACKETS.individual__alternateIds, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.individual__dateOfBirth = Slot( + uri=PHENOPACKETS.dateOfBirth, + name="individual__dateOfBirth", + curie=PHENOPACKETS.curie("dateOfBirth"), + model_uri=PHENOPACKETS.individual__dateOfBirth, + domain=None, + range=Optional[str], +) + +slots.individual__gender = Slot( + uri=PHENOPACKETS.gender, + name="individual__gender", + curie=PHENOPACKETS.curie("gender"), + model_uri=PHENOPACKETS.individual__gender, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.individual__id = Slot( + uri=PHENOPACKETS.id, + name="individual__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.individual__id, + domain=None, + range=Optional[str], +) + +slots.individual__karyotypicSex = Slot( + uri=PHENOPACKETS.karyotypicSex, + name="individual__karyotypicSex", + curie=PHENOPACKETS.curie("karyotypicSex"), + model_uri=PHENOPACKETS.individual__karyotypicSex, + domain=None, + range=Optional[Union[str, "KaryotypicSex"]], +) + +slots.individual__sex = Slot( + uri=PHENOPACKETS.sex, + name="individual__sex", + curie=PHENOPACKETS.curie("sex"), + model_uri=PHENOPACKETS.individual__sex, + domain=None, + range=Optional[Union[str, "Sex"]], +) + +slots.individual__taxonomy = Slot( + uri=PHENOPACKETS.taxonomy, + name="individual__taxonomy", + curie=PHENOPACKETS.curie("taxonomy"), + model_uri=PHENOPACKETS.individual__taxonomy, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.individual__timeAtLastEncounter = Slot( + uri=PHENOPACKETS.timeAtLastEncounter, + name="individual__timeAtLastEncounter", + curie=PHENOPACKETS.curie("timeAtLastEncounter"), + model_uri=PHENOPACKETS.individual__timeAtLastEncounter, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.individual__vitalStatus = Slot( + uri=PHENOPACKETS.vitalStatus, + name="individual__vitalStatus", + curie=PHENOPACKETS.curie("vitalStatus"), + model_uri=PHENOPACKETS.individual__vitalStatus, + domain=None, + range=Optional[Union[dict, VitalStatus]], +) + +slots.vitalStatus__causeOfDeath = Slot( + uri=PHENOPACKETS.causeOfDeath, + name="vitalStatus__causeOfDeath", + curie=PHENOPACKETS.curie("causeOfDeath"), + model_uri=PHENOPACKETS.vitalStatus__causeOfDeath, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.vitalStatus__status = Slot( + uri=PHENOPACKETS.status, + name="vitalStatus__status", + curie=PHENOPACKETS.curie("status"), + model_uri=PHENOPACKETS.vitalStatus__status, + domain=None, + range=Optional[Union[str, "Status"]], +) + +slots.vitalStatus__survivalTimeInDays = Slot( + uri=PHENOPACKETS.survivalTimeInDays, + name="vitalStatus__survivalTimeInDays", + curie=PHENOPACKETS.curie("survivalTimeInDays"), + model_uri=PHENOPACKETS.vitalStatus__survivalTimeInDays, + domain=None, + range=Optional[int], +) + +slots.vitalStatus__timeOfDeath = Slot( + uri=PHENOPACKETS.timeOfDeath, + name="vitalStatus__timeOfDeath", + curie=PHENOPACKETS.curie("timeOfDeath"), + model_uri=PHENOPACKETS.vitalStatus__timeOfDeath, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.complexValue__typedQuantities = Slot( + uri=PHENOPACKETS.typedQuantities, + name="complexValue__typedQuantities", + curie=PHENOPACKETS.curie("typedQuantities"), + model_uri=PHENOPACKETS.complexValue__typedQuantities, + domain=None, + range=Optional[Union[Union[dict, TypedQuantity], list[Union[dict, TypedQuantity]]]], +) + +slots.measurement__assay = Slot( + uri=PHENOPACKETS.assay, + name="measurement__assay", + curie=PHENOPACKETS.curie("assay"), + model_uri=PHENOPACKETS.measurement__assay, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.measurement__complexValue = Slot( + uri=PHENOPACKETS.complexValue, + name="measurement__complexValue", + curie=PHENOPACKETS.curie("complexValue"), + model_uri=PHENOPACKETS.measurement__complexValue, + domain=None, + range=Optional[Union[dict, ComplexValue]], +) + +slots.measurement__description = Slot( + uri=PHENOPACKETS.description, + name="measurement__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.measurement__description, + domain=None, + range=Optional[str], +) + +slots.measurement__procedure = Slot( + uri=PHENOPACKETS.procedure, + name="measurement__procedure", + curie=PHENOPACKETS.curie("procedure"), + model_uri=PHENOPACKETS.measurement__procedure, + domain=None, + range=Optional[Union[dict, Procedure]], +) + +slots.measurement__timeObserved = Slot( + uri=PHENOPACKETS.timeObserved, + name="measurement__timeObserved", + curie=PHENOPACKETS.curie("timeObserved"), + model_uri=PHENOPACKETS.measurement__timeObserved, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.measurement__value = Slot( + uri=PHENOPACKETS.value, + name="measurement__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.measurement__value, + domain=None, + range=Optional[Union[dict, Value]], +) + +slots.quantity__referenceRange = Slot( + uri=PHENOPACKETS.referenceRange, + name="quantity__referenceRange", + curie=PHENOPACKETS.curie("referenceRange"), + model_uri=PHENOPACKETS.quantity__referenceRange, + domain=None, + range=Optional[Union[dict, ReferenceRange]], +) + +slots.quantity__unit = Slot( + uri=PHENOPACKETS.unit, + name="quantity__unit", + curie=PHENOPACKETS.curie("unit"), + model_uri=PHENOPACKETS.quantity__unit, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.quantity__value = Slot( + uri=PHENOPACKETS.value, + name="quantity__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.quantity__value, + domain=None, + range=Optional[float], +) + +slots.referenceRange__high = Slot( + uri=PHENOPACKETS.high, + name="referenceRange__high", + curie=PHENOPACKETS.curie("high"), + model_uri=PHENOPACKETS.referenceRange__high, + domain=None, + range=Optional[float], +) + +slots.referenceRange__low = Slot( + uri=PHENOPACKETS.low, + name="referenceRange__low", + curie=PHENOPACKETS.curie("low"), + model_uri=PHENOPACKETS.referenceRange__low, + domain=None, + range=Optional[float], +) + +slots.referenceRange__unit = Slot( + uri=PHENOPACKETS.unit, + name="referenceRange__unit", + curie=PHENOPACKETS.curie("unit"), + model_uri=PHENOPACKETS.referenceRange__unit, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.typedQuantity__quantity = Slot( + uri=PHENOPACKETS.quantity, + name="typedQuantity__quantity", + curie=PHENOPACKETS.curie("quantity"), + model_uri=PHENOPACKETS.typedQuantity__quantity, + domain=None, + range=Optional[Union[dict, Quantity]], +) + +slots.typedQuantity__type = Slot( + uri=PHENOPACKETS.type, + name="typedQuantity__type", + curie=PHENOPACKETS.curie("type"), + model_uri=PHENOPACKETS.typedQuantity__type, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.value__ontologyClass = Slot( + uri=PHENOPACKETS.ontologyClass, + name="value__ontologyClass", + curie=PHENOPACKETS.curie("ontologyClass"), + model_uri=PHENOPACKETS.value__ontologyClass, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.value__quantity = Slot( + uri=PHENOPACKETS.quantity, + name="value__quantity", + curie=PHENOPACKETS.curie("quantity"), + model_uri=PHENOPACKETS.value__quantity, + domain=None, + range=Optional[Union[dict, Quantity]], +) + +slots.doseInterval__interval = Slot( + uri=PHENOPACKETS.interval, + name="doseInterval__interval", + curie=PHENOPACKETS.curie("interval"), + model_uri=PHENOPACKETS.doseInterval__interval, + domain=None, + range=Optional[Union[dict, TimeInterval]], +) + +slots.doseInterval__quantity = Slot( + uri=PHENOPACKETS.quantity, + name="doseInterval__quantity", + curie=PHENOPACKETS.curie("quantity"), + model_uri=PHENOPACKETS.doseInterval__quantity, + domain=None, + range=Optional[Union[dict, Quantity]], +) + +slots.doseInterval__scheduleFrequency = Slot( + uri=PHENOPACKETS.scheduleFrequency, + name="doseInterval__scheduleFrequency", + curie=PHENOPACKETS.curie("scheduleFrequency"), + model_uri=PHENOPACKETS.doseInterval__scheduleFrequency, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.medicalAction__adverseEvents = Slot( + uri=PHENOPACKETS.adverseEvents, + name="medicalAction__adverseEvents", + curie=PHENOPACKETS.curie("adverseEvents"), + model_uri=PHENOPACKETS.medicalAction__adverseEvents, + domain=None, + range=Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ], +) + +slots.medicalAction__procedure = Slot( + uri=PHENOPACKETS.procedure, + name="medicalAction__procedure", + curie=PHENOPACKETS.curie("procedure"), + model_uri=PHENOPACKETS.medicalAction__procedure, + domain=None, + range=Optional[Union[dict, Procedure]], +) + +slots.medicalAction__radiationTherapy = Slot( + uri=PHENOPACKETS.radiationTherapy, + name="medicalAction__radiationTherapy", + curie=PHENOPACKETS.curie("radiationTherapy"), + model_uri=PHENOPACKETS.medicalAction__radiationTherapy, + domain=None, + range=Optional[Union[dict, RadiationTherapy]], +) + +slots.medicalAction__responseToTreatment = Slot( + uri=PHENOPACKETS.responseToTreatment, + name="medicalAction__responseToTreatment", + curie=PHENOPACKETS.curie("responseToTreatment"), + model_uri=PHENOPACKETS.medicalAction__responseToTreatment, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.medicalAction__therapeuticRegimen = Slot( + uri=PHENOPACKETS.therapeuticRegimen, + name="medicalAction__therapeuticRegimen", + curie=PHENOPACKETS.curie("therapeuticRegimen"), + model_uri=PHENOPACKETS.medicalAction__therapeuticRegimen, + domain=None, + range=Optional[Union[dict, TherapeuticRegimen]], +) + +slots.medicalAction__treatment = Slot( + uri=PHENOPACKETS.treatment, + name="medicalAction__treatment", + curie=PHENOPACKETS.curie("treatment"), + model_uri=PHENOPACKETS.medicalAction__treatment, + domain=None, + range=Optional[Union[dict, Treatment]], +) + +slots.medicalAction__treatmentIntent = Slot( + uri=PHENOPACKETS.treatmentIntent, + name="medicalAction__treatmentIntent", + curie=PHENOPACKETS.curie("treatmentIntent"), + model_uri=PHENOPACKETS.medicalAction__treatmentIntent, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.medicalAction__treatmentTarget = Slot( + uri=PHENOPACKETS.treatmentTarget, + name="medicalAction__treatmentTarget", + curie=PHENOPACKETS.curie("treatmentTarget"), + model_uri=PHENOPACKETS.medicalAction__treatmentTarget, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.medicalAction__treatmentTerminationReason = Slot( + uri=PHENOPACKETS.treatmentTerminationReason, + name="medicalAction__treatmentTerminationReason", + curie=PHENOPACKETS.curie("treatmentTerminationReason"), + model_uri=PHENOPACKETS.medicalAction__treatmentTerminationReason, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.radiationTherapy__bodySite = Slot( + uri=PHENOPACKETS.bodySite, + name="radiationTherapy__bodySite", + curie=PHENOPACKETS.curie("bodySite"), + model_uri=PHENOPACKETS.radiationTherapy__bodySite, + domain=None, + range=Union[dict, OntologyClass], +) + +slots.radiationTherapy__dosage = Slot( + uri=PHENOPACKETS.dosage, + name="radiationTherapy__dosage", + curie=PHENOPACKETS.curie("dosage"), + model_uri=PHENOPACKETS.radiationTherapy__dosage, + domain=None, + range=int, +) + +slots.radiationTherapy__fractions = Slot( + uri=PHENOPACKETS.fractions, + name="radiationTherapy__fractions", + curie=PHENOPACKETS.curie("fractions"), + model_uri=PHENOPACKETS.radiationTherapy__fractions, + domain=None, + range=int, +) + +slots.radiationTherapy__modality = Slot( + uri=PHENOPACKETS.modality, + name="radiationTherapy__modality", + curie=PHENOPACKETS.curie("modality"), + model_uri=PHENOPACKETS.radiationTherapy__modality, + domain=None, + range=Union[dict, OntologyClass], +) + +slots.therapeuticRegimen__endTime = Slot( + uri=PHENOPACKETS.endTime, + name="therapeuticRegimen__endTime", + curie=PHENOPACKETS.curie("endTime"), + model_uri=PHENOPACKETS.therapeuticRegimen__endTime, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.therapeuticRegimen__externalReference = Slot( + uri=PHENOPACKETS.externalReference, + name="therapeuticRegimen__externalReference", + curie=PHENOPACKETS.curie("externalReference"), + model_uri=PHENOPACKETS.therapeuticRegimen__externalReference, + domain=None, + range=Optional[Union[dict, ExternalReference]], +) + +slots.therapeuticRegimen__ontologyClass = Slot( + uri=PHENOPACKETS.ontologyClass, + name="therapeuticRegimen__ontologyClass", + curie=PHENOPACKETS.curie("ontologyClass"), + model_uri=PHENOPACKETS.therapeuticRegimen__ontologyClass, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.therapeuticRegimen__regimenStatus = Slot( + uri=PHENOPACKETS.regimenStatus, + name="therapeuticRegimen__regimenStatus", + curie=PHENOPACKETS.curie("regimenStatus"), + model_uri=PHENOPACKETS.therapeuticRegimen__regimenStatus, + domain=None, + range=Optional[Union[str, "RegimenStatus"]], +) + +slots.therapeuticRegimen__startTime = Slot( + uri=PHENOPACKETS.startTime, + name="therapeuticRegimen__startTime", + curie=PHENOPACKETS.curie("startTime"), + model_uri=PHENOPACKETS.therapeuticRegimen__startTime, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.treatment__agent = Slot( + uri=PHENOPACKETS.agent, + name="treatment__agent", + curie=PHENOPACKETS.curie("agent"), + model_uri=PHENOPACKETS.treatment__agent, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.treatment__cumulativeDose = Slot( + uri=PHENOPACKETS.cumulativeDose, + name="treatment__cumulativeDose", + curie=PHENOPACKETS.curie("cumulativeDose"), + model_uri=PHENOPACKETS.treatment__cumulativeDose, + domain=None, + range=Optional[Union[dict, Quantity]], +) + +slots.treatment__doseIntervals = Slot( + uri=PHENOPACKETS.doseIntervals, + name="treatment__doseIntervals", + curie=PHENOPACKETS.curie("doseIntervals"), + model_uri=PHENOPACKETS.treatment__doseIntervals, + domain=None, + range=Optional[Union[Union[dict, DoseInterval], list[Union[dict, DoseInterval]]]], +) + +slots.treatment__drugType = Slot( + uri=PHENOPACKETS.drugType, + name="treatment__drugType", + curie=PHENOPACKETS.curie("drugType"), + model_uri=PHENOPACKETS.treatment__drugType, + domain=None, + range=Optional[Union[str, "DrugType"]], +) + +slots.treatment__routeOfAdministration = Slot( + uri=PHENOPACKETS.routeOfAdministration, + name="treatment__routeOfAdministration", + curie=PHENOPACKETS.curie("routeOfAdministration"), + model_uri=PHENOPACKETS.treatment__routeOfAdministration, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.metaData__created = Slot( + uri=PHENOPACKETS.created, + name="metaData__created", + curie=PHENOPACKETS.curie("created"), + model_uri=PHENOPACKETS.metaData__created, + domain=None, + range=Optional[str], +) + +slots.metaData__createdBy = Slot( + uri=PHENOPACKETS.createdBy, + name="metaData__createdBy", + curie=PHENOPACKETS.curie("createdBy"), + model_uri=PHENOPACKETS.metaData__createdBy, + domain=None, + range=Optional[str], +) + +slots.metaData__externalReferences = Slot( + uri=PHENOPACKETS.externalReferences, + name="metaData__externalReferences", + curie=PHENOPACKETS.curie("externalReferences"), + model_uri=PHENOPACKETS.metaData__externalReferences, + domain=None, + range=Optional[Union[Union[dict, ExternalReference], list[Union[dict, ExternalReference]]]], +) + +slots.metaData__phenopacketSchemaVersion = Slot( + uri=PHENOPACKETS.phenopacketSchemaVersion, + name="metaData__phenopacketSchemaVersion", + curie=PHENOPACKETS.curie("phenopacketSchemaVersion"), + model_uri=PHENOPACKETS.metaData__phenopacketSchemaVersion, + domain=None, + range=Optional[str], +) + +slots.metaData__resources = Slot( + uri=PHENOPACKETS.resources, + name="metaData__resources", + curie=PHENOPACKETS.curie("resources"), + model_uri=PHENOPACKETS.metaData__resources, + domain=None, + range=Optional[Union[Union[dict, Resource], list[Union[dict, Resource]]]], +) + +slots.metaData__submittedBy = Slot( + uri=PHENOPACKETS.submittedBy, + name="metaData__submittedBy", + curie=PHENOPACKETS.curie("submittedBy"), + model_uri=PHENOPACKETS.metaData__submittedBy, + domain=None, + range=Optional[str], +) + +slots.metaData__updates = Slot( + uri=PHENOPACKETS.updates, + name="metaData__updates", + curie=PHENOPACKETS.curie("updates"), + model_uri=PHENOPACKETS.metaData__updates, + domain=None, + range=Optional[Union[Union[dict, Update], list[Union[dict, Update]]]], +) + +slots.resource__id = Slot( + uri=PHENOPACKETS.id, + name="resource__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.resource__id, + domain=None, + range=Optional[str], +) + +slots.resource__iriPrefix = Slot( + uri=PHENOPACKETS.iriPrefix, + name="resource__iriPrefix", + curie=PHENOPACKETS.curie("iriPrefix"), + model_uri=PHENOPACKETS.resource__iriPrefix, + domain=None, + range=Optional[str], +) + +slots.resource__name = Slot( + uri=PHENOPACKETS.name, + name="resource__name", + curie=PHENOPACKETS.curie("name"), + model_uri=PHENOPACKETS.resource__name, + domain=None, + range=Optional[str], +) + +slots.resource__namespacePrefix = Slot( + uri=PHENOPACKETS.namespacePrefix, + name="resource__namespacePrefix", + curie=PHENOPACKETS.curie("namespacePrefix"), + model_uri=PHENOPACKETS.resource__namespacePrefix, + domain=None, + range=Optional[str], +) + +slots.resource__url = Slot( + uri=PHENOPACKETS.url, + name="resource__url", + curie=PHENOPACKETS.curie("url"), + model_uri=PHENOPACKETS.resource__url, + domain=None, + range=Optional[str], +) + +slots.resource__version = Slot( + uri=PHENOPACKETS.version, + name="resource__version", + curie=PHENOPACKETS.curie("version"), + model_uri=PHENOPACKETS.resource__version, + domain=None, + range=Optional[str], +) + +slots.update__comment = Slot( + uri=PHENOPACKETS.comment, + name="update__comment", + curie=PHENOPACKETS.curie("comment"), + model_uri=PHENOPACKETS.update__comment, + domain=None, + range=Optional[str], +) + +slots.update__timestamp = Slot( + uri=PHENOPACKETS.timestamp, + name="update__timestamp", + curie=PHENOPACKETS.curie("timestamp"), + model_uri=PHENOPACKETS.update__timestamp, + domain=None, + range=str, +) + +slots.update__updatedBy = Slot( + uri=PHENOPACKETS.updatedBy, + name="update__updatedBy", + curie=PHENOPACKETS.curie("updatedBy"), + model_uri=PHENOPACKETS.update__updatedBy, + domain=None, + range=Optional[str], +) + +slots.pedigree__persons = Slot( + uri=PHENOPACKETS.persons, + name="pedigree__persons", + curie=PHENOPACKETS.curie("persons"), + model_uri=PHENOPACKETS.pedigree__persons, + domain=None, + range=Optional[Union[Union[dict, Person], list[Union[dict, Person]]]], +) + +slots.person__affectedStatus = Slot( + uri=PHENOPACKETS.affectedStatus, + name="person__affectedStatus", + curie=PHENOPACKETS.curie("affectedStatus"), + model_uri=PHENOPACKETS.person__affectedStatus, + domain=None, + range=Optional[Union[str, "AffectedStatus"]], +) + +slots.person__familyId = Slot( + uri=PHENOPACKETS.familyId, + name="person__familyId", + curie=PHENOPACKETS.curie("familyId"), + model_uri=PHENOPACKETS.person__familyId, + domain=None, + range=Optional[str], +) + +slots.person__individualId = Slot( + uri=PHENOPACKETS.individualId, + name="person__individualId", + curie=PHENOPACKETS.curie("individualId"), + model_uri=PHENOPACKETS.person__individualId, + domain=None, + range=Optional[str], +) + +slots.person__maternalId = Slot( + uri=PHENOPACKETS.maternalId, + name="person__maternalId", + curie=PHENOPACKETS.curie("maternalId"), + model_uri=PHENOPACKETS.person__maternalId, + domain=None, + range=Optional[str], +) + +slots.person__paternalId = Slot( + uri=PHENOPACKETS.paternalId, + name="person__paternalId", + curie=PHENOPACKETS.curie("paternalId"), + model_uri=PHENOPACKETS.person__paternalId, + domain=None, + range=Optional[str], +) + +slots.person__sex = Slot( + uri=PHENOPACKETS.sex, + name="person__sex", + curie=PHENOPACKETS.curie("sex"), + model_uri=PHENOPACKETS.person__sex, + domain=None, + range=Optional[Union[str, "Sex"]], +) + +slots.phenotypicFeature__description = Slot( + uri=PHENOPACKETS.description, + name="phenotypicFeature__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.phenotypicFeature__description, + domain=None, + range=Optional[str], +) + +slots.phenotypicFeature__evidence = Slot( + uri=PHENOPACKETS.evidence, + name="phenotypicFeature__evidence", + curie=PHENOPACKETS.curie("evidence"), + model_uri=PHENOPACKETS.phenotypicFeature__evidence, + domain=None, + range=Optional[Union[Union[dict, Evidence], list[Union[dict, Evidence]]]], +) + +slots.phenotypicFeature__excluded = Slot( + uri=PHENOPACKETS.excluded, + name="phenotypicFeature__excluded", + curie=PHENOPACKETS.curie("excluded"), + model_uri=PHENOPACKETS.phenotypicFeature__excluded, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.phenotypicFeature__modifiers = Slot( + uri=PHENOPACKETS.modifiers, + name="phenotypicFeature__modifiers", + curie=PHENOPACKETS.curie("modifiers"), + model_uri=PHENOPACKETS.phenotypicFeature__modifiers, + domain=None, + range=Optional[ + Union[dict[Union[str, OntologyClassId], Union[dict, OntologyClass]], list[Union[dict, OntologyClass]]] + ], +) + +slots.phenotypicFeature__onset = Slot( + uri=PHENOPACKETS.onset, + name="phenotypicFeature__onset", + curie=PHENOPACKETS.curie("onset"), + model_uri=PHENOPACKETS.phenotypicFeature__onset, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.phenotypicFeature__resolution = Slot( + uri=PHENOPACKETS.resolution, + name="phenotypicFeature__resolution", + curie=PHENOPACKETS.curie("resolution"), + model_uri=PHENOPACKETS.phenotypicFeature__resolution, + domain=None, + range=Optional[Union[dict, TimeElement]], +) + +slots.phenotypicFeature__severity = Slot( + uri=PHENOPACKETS.severity, + name="phenotypicFeature__severity", + curie=PHENOPACKETS.curie("severity"), + model_uri=PHENOPACKETS.phenotypicFeature__severity, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.phenotypicFeature__type = Slot( + uri=PHENOPACKETS.type, + name="phenotypicFeature__type", + curie=PHENOPACKETS.curie("type"), + model_uri=PHENOPACKETS.phenotypicFeature__type, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.timestamp__nanos = Slot( + uri=PHENOPACKETS.nanos, + name="timestamp__nanos", + curie=PHENOPACKETS.curie("nanos"), + model_uri=PHENOPACKETS.timestamp__nanos, + domain=None, + range=Optional[int], +) + +slots.timestamp__seconds = Slot( + uri=PHENOPACKETS.seconds, + name="timestamp__seconds", + curie=PHENOPACKETS.curie("seconds"), + model_uri=PHENOPACKETS.timestamp__seconds, + domain=None, + range=Optional[int], +) + +slots.expression__syntax = Slot( + uri=PHENOPACKETS.syntax, + name="expression__syntax", + curie=PHENOPACKETS.curie("syntax"), + model_uri=PHENOPACKETS.expression__syntax, + domain=None, + range=Optional[str], +) + +slots.expression__value = Slot( + uri=PHENOPACKETS.value, + name="expression__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.expression__value, + domain=None, + range=Optional[str], +) + +slots.expression__version = Slot( + uri=PHENOPACKETS.version, + name="expression__version", + curie=PHENOPACKETS.curie("version"), + model_uri=PHENOPACKETS.expression__version, + domain=None, + range=Optional[str], +) + +slots.extension__name = Slot( + uri=PHENOPACKETS.name, + name="extension__name", + curie=PHENOPACKETS.curie("name"), + model_uri=PHENOPACKETS.extension__name, + domain=None, + range=Optional[str], +) + +slots.extension__value = Slot( + uri=PHENOPACKETS.value, + name="extension__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.extension__value, + domain=None, + range=Optional[Union[Union[dict, Any], list[Union[dict, Any]]]], +) + +slots.geneDescriptor__alternateIds = Slot( + uri=PHENOPACKETS.alternateIds, + name="geneDescriptor__alternateIds", + curie=PHENOPACKETS.curie("alternateIds"), + model_uri=PHENOPACKETS.geneDescriptor__alternateIds, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.geneDescriptor__alternateSymbols = Slot( + uri=PHENOPACKETS.alternateSymbols, + name="geneDescriptor__alternateSymbols", + curie=PHENOPACKETS.curie("alternateSymbols"), + model_uri=PHENOPACKETS.geneDescriptor__alternateSymbols, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.geneDescriptor__description = Slot( + uri=PHENOPACKETS.description, + name="geneDescriptor__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.geneDescriptor__description, + domain=None, + range=Optional[str], +) + +slots.geneDescriptor__symbol = Slot( + uri=PHENOPACKETS.symbol, + name="geneDescriptor__symbol", + curie=PHENOPACKETS.curie("symbol"), + model_uri=PHENOPACKETS.geneDescriptor__symbol, + domain=None, + range=Optional[str], +) + +slots.geneDescriptor__valueId = Slot( + uri=PHENOPACKETS.valueId, + name="geneDescriptor__valueId", + curie=PHENOPACKETS.curie("valueId"), + model_uri=PHENOPACKETS.geneDescriptor__valueId, + domain=None, + range=Optional[str], +) + +slots.geneDescriptor__xrefs = Slot( + uri=PHENOPACKETS.xrefs, + name="geneDescriptor__xrefs", + curie=PHENOPACKETS.curie("xrefs"), + model_uri=PHENOPACKETS.geneDescriptor__xrefs, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.variationDescriptor__allelicState = Slot( + uri=PHENOPACKETS.allelicState, + name="variationDescriptor__allelicState", + curie=PHENOPACKETS.curie("allelicState"), + model_uri=PHENOPACKETS.variationDescriptor__allelicState, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.variationDescriptor__alternateLabels = Slot( + uri=PHENOPACKETS.alternateLabels, + name="variationDescriptor__alternateLabels", + curie=PHENOPACKETS.curie("alternateLabels"), + model_uri=PHENOPACKETS.variationDescriptor__alternateLabels, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.variationDescriptor__description = Slot( + uri=PHENOPACKETS.description, + name="variationDescriptor__description", + curie=PHENOPACKETS.curie("description"), + model_uri=PHENOPACKETS.variationDescriptor__description, + domain=None, + range=Optional[str], +) + +slots.variationDescriptor__expressions = Slot( + uri=PHENOPACKETS.expressions, + name="variationDescriptor__expressions", + curie=PHENOPACKETS.curie("expressions"), + model_uri=PHENOPACKETS.variationDescriptor__expressions, + domain=None, + range=Optional[Union[Union[dict, Expression], list[Union[dict, Expression]]]], +) + +slots.variationDescriptor__extensions = Slot( + uri=PHENOPACKETS.extensions, + name="variationDescriptor__extensions", + curie=PHENOPACKETS.curie("extensions"), + model_uri=PHENOPACKETS.variationDescriptor__extensions, + domain=None, + range=Optional[Union[Union[dict, Extension], list[Union[dict, Extension]]]], +) + +slots.variationDescriptor__geneContext = Slot( + uri=PHENOPACKETS.geneContext, + name="variationDescriptor__geneContext", + curie=PHENOPACKETS.curie("geneContext"), + model_uri=PHENOPACKETS.variationDescriptor__geneContext, + domain=None, + range=Optional[Union[dict, GeneDescriptor]], +) + +slots.variationDescriptor__id = Slot( + uri=PHENOPACKETS.id, + name="variationDescriptor__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.variationDescriptor__id, + domain=None, + range=Optional[str], +) + +slots.variationDescriptor__label = Slot( + uri=PHENOPACKETS.label, + name="variationDescriptor__label", + curie=PHENOPACKETS.curie("label"), + model_uri=PHENOPACKETS.variationDescriptor__label, + domain=None, + range=Optional[str], +) + +slots.variationDescriptor__moleculeContext = Slot( + uri=PHENOPACKETS.moleculeContext, + name="variationDescriptor__moleculeContext", + curie=PHENOPACKETS.curie("moleculeContext"), + model_uri=PHENOPACKETS.variationDescriptor__moleculeContext, + domain=None, + range=Optional[Union[str, "MoleculeContext"]], +) + +slots.variationDescriptor__structuralType = Slot( + uri=PHENOPACKETS.structuralType, + name="variationDescriptor__structuralType", + curie=PHENOPACKETS.curie("structuralType"), + model_uri=PHENOPACKETS.variationDescriptor__structuralType, + domain=None, + range=Optional[Union[dict, OntologyClass]], +) + +slots.variationDescriptor__variation = Slot( + uri=PHENOPACKETS.variation, + name="variationDescriptor__variation", + curie=PHENOPACKETS.curie("variation"), + model_uri=PHENOPACKETS.variationDescriptor__variation, + domain=None, + range=Optional[Union[dict, Variation]], +) + +slots.variationDescriptor__vcfRecord = Slot( + uri=PHENOPACKETS.vcfRecord, + name="variationDescriptor__vcfRecord", + curie=PHENOPACKETS.curie("vcfRecord"), + model_uri=PHENOPACKETS.variationDescriptor__vcfRecord, + domain=None, + range=Optional[Union[dict, VcfRecord]], +) + +slots.variationDescriptor__vrsRefAlleleSeq = Slot( + uri=PHENOPACKETS.vrsRefAlleleSeq, + name="variationDescriptor__vrsRefAlleleSeq", + curie=PHENOPACKETS.curie("vrsRefAlleleSeq"), + model_uri=PHENOPACKETS.variationDescriptor__vrsRefAlleleSeq, + domain=None, + range=Optional[str], +) + +slots.variationDescriptor__xrefs = Slot( + uri=PHENOPACKETS.xrefs, + name="variationDescriptor__xrefs", + curie=PHENOPACKETS.curie("xrefs"), + model_uri=PHENOPACKETS.variationDescriptor__xrefs, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.vcfRecord__alt = Slot( + uri=PHENOPACKETS.alt, + name="vcfRecord__alt", + curie=PHENOPACKETS.curie("alt"), + model_uri=PHENOPACKETS.vcfRecord__alt, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__chrom = Slot( + uri=PHENOPACKETS.chrom, + name="vcfRecord__chrom", + curie=PHENOPACKETS.curie("chrom"), + model_uri=PHENOPACKETS.vcfRecord__chrom, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__filter = Slot( + uri=PHENOPACKETS.filter, + name="vcfRecord__filter", + curie=PHENOPACKETS.curie("filter"), + model_uri=PHENOPACKETS.vcfRecord__filter, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__genomeAssembly = Slot( + uri=PHENOPACKETS.genomeAssembly, + name="vcfRecord__genomeAssembly", + curie=PHENOPACKETS.curie("genomeAssembly"), + model_uri=PHENOPACKETS.vcfRecord__genomeAssembly, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__id = Slot( + uri=PHENOPACKETS.id, + name="vcfRecord__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.vcfRecord__id, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__info = Slot( + uri=PHENOPACKETS.info, + name="vcfRecord__info", + curie=PHENOPACKETS.curie("info"), + model_uri=PHENOPACKETS.vcfRecord__info, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__pos = Slot( + uri=PHENOPACKETS.pos, + name="vcfRecord__pos", + curie=PHENOPACKETS.curie("pos"), + model_uri=PHENOPACKETS.vcfRecord__pos, + domain=None, + range=Optional[int], +) + +slots.vcfRecord__qual = Slot( + uri=PHENOPACKETS.qual, + name="vcfRecord__qual", + curie=PHENOPACKETS.curie("qual"), + model_uri=PHENOPACKETS.vcfRecord__qual, + domain=None, + range=Optional[str], +) + +slots.vcfRecord__ref = Slot( + uri=PHENOPACKETS.ref, + name="vcfRecord__ref", + curie=PHENOPACKETS.curie("ref"), + model_uri=PHENOPACKETS.vcfRecord__ref, + domain=None, + range=Optional[str], +) + +slots.any__typeUrl = Slot( + uri=PHENOPACKETS.typeUrl, + name="any__typeUrl", + curie=PHENOPACKETS.curie("typeUrl"), + model_uri=PHENOPACKETS.any__typeUrl, + domain=None, + range=Optional[str], +) + +slots.any__value = Slot( + uri=PHENOPACKETS.value, + name="any__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.any__value, + domain=None, + range=Optional[str], +) + +slots.abundance__copyNumber = Slot( + uri=PHENOPACKETS.copyNumber, + name="abundance__copyNumber", + curie=PHENOPACKETS.curie("copyNumber"), + model_uri=PHENOPACKETS.abundance__copyNumber, + domain=None, + range=Optional[Union[dict, CopyNumber]], +) + +slots.allele__chromosomeLocation = Slot( + uri=PHENOPACKETS.chromosomeLocation, + name="allele__chromosomeLocation", + curie=PHENOPACKETS.curie("chromosomeLocation"), + model_uri=PHENOPACKETS.allele__chromosomeLocation, + domain=None, + range=Optional[Union[dict, ChromosomeLocation]], +) + +slots.allele__curie = Slot( + uri=PHENOPACKETS.curie, + name="allele__curie", + curie=PHENOPACKETS.curie("curie"), + model_uri=PHENOPACKETS.allele__curie, + domain=None, + range=Optional[str], +) + +slots.allele__derivedSequenceExpression = Slot( + uri=PHENOPACKETS.derivedSequenceExpression, + name="allele__derivedSequenceExpression", + curie=PHENOPACKETS.curie("derivedSequenceExpression"), + model_uri=PHENOPACKETS.allele__derivedSequenceExpression, + domain=None, + range=Optional[Union[dict, DerivedSequenceExpression]], +) + +slots.allele__id = Slot( + uri=PHENOPACKETS.id, + name="allele__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.allele__id, + domain=None, + range=Optional[str], +) + +slots.allele__literalSequenceExpression = Slot( + uri=PHENOPACKETS.literalSequenceExpression, + name="allele__literalSequenceExpression", + curie=PHENOPACKETS.curie("literalSequenceExpression"), + model_uri=PHENOPACKETS.allele__literalSequenceExpression, + domain=None, + range=Optional[Union[dict, LiteralSequenceExpression]], +) + +slots.allele__repeatedSequenceExpression = Slot( + uri=PHENOPACKETS.repeatedSequenceExpression, + name="allele__repeatedSequenceExpression", + curie=PHENOPACKETS.curie("repeatedSequenceExpression"), + model_uri=PHENOPACKETS.allele__repeatedSequenceExpression, + domain=None, + range=Optional[Union[dict, RepeatedSequenceExpression]], +) + +slots.allele__sequenceLocation = Slot( + uri=PHENOPACKETS.sequenceLocation, + name="allele__sequenceLocation", + curie=PHENOPACKETS.curie("sequenceLocation"), + model_uri=PHENOPACKETS.allele__sequenceLocation, + domain=None, + range=Optional[Union[dict, SequenceLocation]], +) + +slots.chromosomeLocation__chr = Slot( + uri=PHENOPACKETS.chr, + name="chromosomeLocation__chr", + curie=PHENOPACKETS.curie("chr"), + model_uri=PHENOPACKETS.chromosomeLocation__chr, + domain=None, + range=Optional[str], +) + +slots.chromosomeLocation__id = Slot( + uri=PHENOPACKETS.id, + name="chromosomeLocation__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.chromosomeLocation__id, + domain=None, + range=Optional[str], +) + +slots.chromosomeLocation__interval = Slot( + uri=PHENOPACKETS.interval, + name="chromosomeLocation__interval", + curie=PHENOPACKETS.curie("interval"), + model_uri=PHENOPACKETS.chromosomeLocation__interval, + domain=None, + range=Optional[Union[dict, CytobandInterval]], +) + +slots.chromosomeLocation__speciesId = Slot( + uri=PHENOPACKETS.speciesId, + name="chromosomeLocation__speciesId", + curie=PHENOPACKETS.curie("speciesId"), + model_uri=PHENOPACKETS.chromosomeLocation__speciesId, + domain=None, + range=Optional[str], +) + +slots.copyNumber__allele = Slot( + uri=PHENOPACKETS.allele, + name="copyNumber__allele", + curie=PHENOPACKETS.curie("allele"), + model_uri=PHENOPACKETS.copyNumber__allele, + domain=None, + range=Optional[Union[dict, Allele]], +) + +slots.copyNumber__curie = Slot( + uri=PHENOPACKETS.curie, + name="copyNumber__curie", + curie=PHENOPACKETS.curie("curie"), + model_uri=PHENOPACKETS.copyNumber__curie, + domain=None, + range=Optional[str], +) + +slots.copyNumber__definiteRange = Slot( + uri=PHENOPACKETS.definiteRange, + name="copyNumber__definiteRange", + curie=PHENOPACKETS.curie("definiteRange"), + model_uri=PHENOPACKETS.copyNumber__definiteRange, + domain=None, + range=Optional[Union[dict, DefiniteRange]], +) + +slots.copyNumber__derivedSequenceExpression = Slot( + uri=PHENOPACKETS.derivedSequenceExpression, + name="copyNumber__derivedSequenceExpression", + curie=PHENOPACKETS.curie("derivedSequenceExpression"), + model_uri=PHENOPACKETS.copyNumber__derivedSequenceExpression, + domain=None, + range=Optional[Union[dict, DerivedSequenceExpression]], +) + +slots.copyNumber__gene = Slot( + uri=PHENOPACKETS.gene, + name="copyNumber__gene", + curie=PHENOPACKETS.curie("gene"), + model_uri=PHENOPACKETS.copyNumber__gene, + domain=None, + range=Optional[Union[dict, Gene]], +) + +slots.copyNumber__haplotype = Slot( + uri=PHENOPACKETS.haplotype, + name="copyNumber__haplotype", + curie=PHENOPACKETS.curie("haplotype"), + model_uri=PHENOPACKETS.copyNumber__haplotype, + domain=None, + range=Optional[Union[dict, Haplotype]], +) + +slots.copyNumber__id = Slot( + uri=PHENOPACKETS.id, + name="copyNumber__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.copyNumber__id, + domain=None, + range=Optional[str], +) + +slots.copyNumber__indefiniteRange = Slot( + uri=PHENOPACKETS.indefiniteRange, + name="copyNumber__indefiniteRange", + curie=PHENOPACKETS.curie("indefiniteRange"), + model_uri=PHENOPACKETS.copyNumber__indefiniteRange, + domain=None, + range=Optional[Union[dict, IndefiniteRange]], +) + +slots.copyNumber__literalSequenceExpression = Slot( + uri=PHENOPACKETS.literalSequenceExpression, + name="copyNumber__literalSequenceExpression", + curie=PHENOPACKETS.curie("literalSequenceExpression"), + model_uri=PHENOPACKETS.copyNumber__literalSequenceExpression, + domain=None, + range=Optional[Union[dict, LiteralSequenceExpression]], +) + +slots.copyNumber__number = Slot( + uri=PHENOPACKETS.number, + name="copyNumber__number", + curie=PHENOPACKETS.curie("number"), + model_uri=PHENOPACKETS.copyNumber__number, + domain=None, + range=Optional[Union[dict, Number]], +) + +slots.copyNumber__repeatedSequenceExpression = Slot( + uri=PHENOPACKETS.repeatedSequenceExpression, + name="copyNumber__repeatedSequenceExpression", + curie=PHENOPACKETS.curie("repeatedSequenceExpression"), + model_uri=PHENOPACKETS.copyNumber__repeatedSequenceExpression, + domain=None, + range=Optional[Union[dict, RepeatedSequenceExpression]], +) + +slots.cytobandInterval__end = Slot( + uri=PHENOPACKETS.end, + name="cytobandInterval__end", + curie=PHENOPACKETS.curie("end"), + model_uri=PHENOPACKETS.cytobandInterval__end, + domain=None, + range=Optional[str], +) + +slots.cytobandInterval__start = Slot( + uri=PHENOPACKETS.start, + name="cytobandInterval__start", + curie=PHENOPACKETS.curie("start"), + model_uri=PHENOPACKETS.cytobandInterval__start, + domain=None, + range=Optional[str], +) + +slots.definiteRange__max = Slot( + uri=PHENOPACKETS.max, + name="definiteRange__max", + curie=PHENOPACKETS.curie("max"), + model_uri=PHENOPACKETS.definiteRange__max, + domain=None, + range=Optional[int], +) + +slots.definiteRange__min = Slot( + uri=PHENOPACKETS.min, + name="definiteRange__min", + curie=PHENOPACKETS.curie("min"), + model_uri=PHENOPACKETS.definiteRange__min, + domain=None, + range=Optional[int], +) + +slots.derivedSequenceExpression__location = Slot( + uri=PHENOPACKETS.location, + name="derivedSequenceExpression__location", + curie=PHENOPACKETS.curie("location"), + model_uri=PHENOPACKETS.derivedSequenceExpression__location, + domain=None, + range=Optional[Union[dict, SequenceLocation]], +) + +slots.derivedSequenceExpression__reverseComplement = Slot( + uri=PHENOPACKETS.reverseComplement, + name="derivedSequenceExpression__reverseComplement", + curie=PHENOPACKETS.curie("reverseComplement"), + model_uri=PHENOPACKETS.derivedSequenceExpression__reverseComplement, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.feature__gene = Slot( + uri=PHENOPACKETS.gene, + name="feature__gene", + curie=PHENOPACKETS.curie("gene"), + model_uri=PHENOPACKETS.feature__gene, + domain=None, + range=Optional[Union[dict, Gene]], +) + +slots.gene__geneId = Slot( + uri=PHENOPACKETS.geneId, + name="gene__geneId", + curie=PHENOPACKETS.curie("geneId"), + model_uri=PHENOPACKETS.gene__geneId, + domain=None, + range=Optional[str], +) + +slots.indefiniteRange__comparator = Slot( + uri=PHENOPACKETS.comparator, + name="indefiniteRange__comparator", + curie=PHENOPACKETS.curie("comparator"), + model_uri=PHENOPACKETS.indefiniteRange__comparator, + domain=None, + range=Optional[str], +) + +slots.indefiniteRange__value = Slot( + uri=PHENOPACKETS.value, + name="indefiniteRange__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.indefiniteRange__value, + domain=None, + range=Optional[int], +) + +slots.literalSequenceExpression__sequence = Slot( + uri=PHENOPACKETS.sequence, + name="literalSequenceExpression__sequence", + curie=PHENOPACKETS.curie("sequence"), + model_uri=PHENOPACKETS.literalSequenceExpression__sequence, + domain=None, + range=Optional[str], +) + +slots.location__chromosomeLocation = Slot( + uri=PHENOPACKETS.chromosomeLocation, + name="location__chromosomeLocation", + curie=PHENOPACKETS.curie("chromosomeLocation"), + model_uri=PHENOPACKETS.location__chromosomeLocation, + domain=None, + range=Optional[Union[dict, ChromosomeLocation]], +) + +slots.location__sequenceLocation = Slot( + uri=PHENOPACKETS.sequenceLocation, + name="location__sequenceLocation", + curie=PHENOPACKETS.curie("sequenceLocation"), + model_uri=PHENOPACKETS.location__sequenceLocation, + domain=None, + range=Optional[Union[dict, SequenceLocation]], +) + +slots.member__allele = Slot( + uri=PHENOPACKETS.allele, + name="member__allele", + curie=PHENOPACKETS.curie("allele"), + model_uri=PHENOPACKETS.member__allele, + domain=None, + range=Optional[Union[dict, Allele]], +) + +slots.member__copyNumber = Slot( + uri=PHENOPACKETS.copyNumber, + name="member__copyNumber", + curie=PHENOPACKETS.curie("copyNumber"), + model_uri=PHENOPACKETS.member__copyNumber, + domain=None, + range=Optional[Union[dict, CopyNumber]], +) + +slots.member__curie = Slot( + uri=PHENOPACKETS.curie, + name="member__curie", + curie=PHENOPACKETS.curie("curie"), + model_uri=PHENOPACKETS.member__curie, + domain=None, + range=Optional[str], +) + +slots.member__haplotype = Slot( + uri=PHENOPACKETS.haplotype, + name="member__haplotype", + curie=PHENOPACKETS.curie("haplotype"), + model_uri=PHENOPACKETS.member__haplotype, + domain=None, + range=Optional[Union[dict, Haplotype]], +) + +slots.member__id = Slot( + uri=PHENOPACKETS.id, + name="member__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.member__id, + domain=None, + range=Optional[str], +) + +slots.member__members = Slot( + uri=PHENOPACKETS.members, + name="member__members", + curie=PHENOPACKETS.curie("members"), + model_uri=PHENOPACKETS.member__members, + domain=None, + range=Optional[Union[Union[dict, Member], list[Union[dict, Member]]]], +) + +slots.member__text = Slot( + uri=PHENOPACKETS.text, + name="member__text", + curie=PHENOPACKETS.curie("text"), + model_uri=PHENOPACKETS.member__text, + domain=None, + range=Optional[Union[dict, Text]], +) + +slots.member__variationSet = Slot( + uri=PHENOPACKETS.variationSet, + name="member__variationSet", + curie=PHENOPACKETS.curie("variationSet"), + model_uri=PHENOPACKETS.member__variationSet, + domain=None, + range=Optional[Union[dict, VariationSet]], +) + +slots.molecularVariation__allele = Slot( + uri=PHENOPACKETS.allele, + name="molecularVariation__allele", + curie=PHENOPACKETS.curie("allele"), + model_uri=PHENOPACKETS.molecularVariation__allele, + domain=None, + range=Optional[Union[dict, Allele]], +) + +slots.molecularVariation__haplotype = Slot( + uri=PHENOPACKETS.haplotype, + name="molecularVariation__haplotype", + curie=PHENOPACKETS.curie("haplotype"), + model_uri=PHENOPACKETS.molecularVariation__haplotype, + domain=None, + range=Optional[Union[dict, Haplotype]], +) + +slots.number__value = Slot( + uri=PHENOPACKETS.value, + name="number__value", + curie=PHENOPACKETS.curie("value"), + model_uri=PHENOPACKETS.number__value, + domain=None, + range=Optional[int], +) + +slots.repeatedSequenceExpression__definiteRange = Slot( + uri=PHENOPACKETS.definiteRange, + name="repeatedSequenceExpression__definiteRange", + curie=PHENOPACKETS.curie("definiteRange"), + model_uri=PHENOPACKETS.repeatedSequenceExpression__definiteRange, + domain=None, + range=Optional[Union[dict, DefiniteRange]], +) + +slots.repeatedSequenceExpression__derivedSequenceExpression = Slot( + uri=PHENOPACKETS.derivedSequenceExpression, + name="repeatedSequenceExpression__derivedSequenceExpression", + curie=PHENOPACKETS.curie("derivedSequenceExpression"), + model_uri=PHENOPACKETS.repeatedSequenceExpression__derivedSequenceExpression, + domain=None, + range=Optional[Union[dict, DerivedSequenceExpression]], +) + +slots.repeatedSequenceExpression__indefiniteRange = Slot( + uri=PHENOPACKETS.indefiniteRange, + name="repeatedSequenceExpression__indefiniteRange", + curie=PHENOPACKETS.curie("indefiniteRange"), + model_uri=PHENOPACKETS.repeatedSequenceExpression__indefiniteRange, + domain=None, + range=Optional[Union[dict, IndefiniteRange]], +) + +slots.repeatedSequenceExpression__literalSequenceExpression = Slot( + uri=PHENOPACKETS.literalSequenceExpression, + name="repeatedSequenceExpression__literalSequenceExpression", + curie=PHENOPACKETS.curie("literalSequenceExpression"), + model_uri=PHENOPACKETS.repeatedSequenceExpression__literalSequenceExpression, + domain=None, + range=Optional[Union[dict, LiteralSequenceExpression]], +) + +slots.repeatedSequenceExpression__number = Slot( + uri=PHENOPACKETS.number, + name="repeatedSequenceExpression__number", + curie=PHENOPACKETS.curie("number"), + model_uri=PHENOPACKETS.repeatedSequenceExpression__number, + domain=None, + range=Optional[Union[dict, Number]], +) + +slots.sequenceExpression__derivedSequenceExpression = Slot( + uri=PHENOPACKETS.derivedSequenceExpression, + name="sequenceExpression__derivedSequenceExpression", + curie=PHENOPACKETS.curie("derivedSequenceExpression"), + model_uri=PHENOPACKETS.sequenceExpression__derivedSequenceExpression, + domain=None, + range=Optional[Union[dict, DerivedSequenceExpression]], +) + +slots.sequenceExpression__literalSequenceExpression = Slot( + uri=PHENOPACKETS.literalSequenceExpression, + name="sequenceExpression__literalSequenceExpression", + curie=PHENOPACKETS.curie("literalSequenceExpression"), + model_uri=PHENOPACKETS.sequenceExpression__literalSequenceExpression, + domain=None, + range=Optional[Union[dict, LiteralSequenceExpression]], +) + +slots.sequenceExpression__repeatedSequenceExpression = Slot( + uri=PHENOPACKETS.repeatedSequenceExpression, + name="sequenceExpression__repeatedSequenceExpression", + curie=PHENOPACKETS.curie("repeatedSequenceExpression"), + model_uri=PHENOPACKETS.sequenceExpression__repeatedSequenceExpression, + domain=None, + range=Optional[Union[dict, RepeatedSequenceExpression]], +) + +slots.sequenceInterval__endDefiniteRange = Slot( + uri=PHENOPACKETS.endDefiniteRange, + name="sequenceInterval__endDefiniteRange", + curie=PHENOPACKETS.curie("endDefiniteRange"), + model_uri=PHENOPACKETS.sequenceInterval__endDefiniteRange, + domain=None, + range=Optional[Union[dict, DefiniteRange]], +) + +slots.sequenceInterval__endIndefiniteRange = Slot( + uri=PHENOPACKETS.endIndefiniteRange, + name="sequenceInterval__endIndefiniteRange", + curie=PHENOPACKETS.curie("endIndefiniteRange"), + model_uri=PHENOPACKETS.sequenceInterval__endIndefiniteRange, + domain=None, + range=Optional[Union[dict, IndefiniteRange]], +) + +slots.sequenceInterval__endNumber = Slot( + uri=PHENOPACKETS.endNumber, + name="sequenceInterval__endNumber", + curie=PHENOPACKETS.curie("endNumber"), + model_uri=PHENOPACKETS.sequenceInterval__endNumber, + domain=None, + range=Optional[Union[dict, Number]], +) + +slots.sequenceInterval__startDefiniteRange = Slot( + uri=PHENOPACKETS.startDefiniteRange, + name="sequenceInterval__startDefiniteRange", + curie=PHENOPACKETS.curie("startDefiniteRange"), + model_uri=PHENOPACKETS.sequenceInterval__startDefiniteRange, + domain=None, + range=Optional[Union[dict, DefiniteRange]], +) + +slots.sequenceInterval__startIndefiniteRange = Slot( + uri=PHENOPACKETS.startIndefiniteRange, + name="sequenceInterval__startIndefiniteRange", + curie=PHENOPACKETS.curie("startIndefiniteRange"), + model_uri=PHENOPACKETS.sequenceInterval__startIndefiniteRange, + domain=None, + range=Optional[Union[dict, IndefiniteRange]], +) + +slots.sequenceInterval__startNumber = Slot( + uri=PHENOPACKETS.startNumber, + name="sequenceInterval__startNumber", + curie=PHENOPACKETS.curie("startNumber"), + model_uri=PHENOPACKETS.sequenceInterval__startNumber, + domain=None, + range=Optional[Union[dict, Number]], +) + +slots.sequenceLocation__id = Slot( + uri=PHENOPACKETS.id, + name="sequenceLocation__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.sequenceLocation__id, + domain=None, + range=Optional[str], +) + +slots.sequenceLocation__sequenceId = Slot( + uri=PHENOPACKETS.sequenceId, + name="sequenceLocation__sequenceId", + curie=PHENOPACKETS.curie("sequenceId"), + model_uri=PHENOPACKETS.sequenceLocation__sequenceId, + domain=None, + range=Optional[str], +) + +slots.sequenceLocation__sequenceInterval = Slot( + uri=PHENOPACKETS.sequenceInterval, + name="sequenceLocation__sequenceInterval", + curie=PHENOPACKETS.curie("sequenceInterval"), + model_uri=PHENOPACKETS.sequenceLocation__sequenceInterval, + domain=None, + range=Optional[Union[dict, SequenceInterval]], +) + +slots.sequenceState__sequence = Slot( + uri=PHENOPACKETS.sequence, + name="sequenceState__sequence", + curie=PHENOPACKETS.curie("sequence"), + model_uri=PHENOPACKETS.sequenceState__sequence, + domain=None, + range=Optional[str], +) + +slots.simpleInterval__end = Slot( + uri=PHENOPACKETS.end, + name="simpleInterval__end", + curie=PHENOPACKETS.curie("end"), + model_uri=PHENOPACKETS.simpleInterval__end, + domain=None, + range=Optional[int], +) + +slots.simpleInterval__start = Slot( + uri=PHENOPACKETS.start, + name="simpleInterval__start", + curie=PHENOPACKETS.curie("start"), + model_uri=PHENOPACKETS.simpleInterval__start, + domain=None, + range=Optional[int], +) + +slots.systemicVariation__copyNumber = Slot( + uri=PHENOPACKETS.copyNumber, + name="systemicVariation__copyNumber", + curie=PHENOPACKETS.curie("copyNumber"), + model_uri=PHENOPACKETS.systemicVariation__copyNumber, + domain=None, + range=Optional[Union[dict, CopyNumber]], +) + +slots.text__definition = Slot( + uri=PHENOPACKETS.definition, + name="text__definition", + curie=PHENOPACKETS.curie("definition"), + model_uri=PHENOPACKETS.text__definition, + domain=None, + range=Optional[str], +) + +slots.text__id = Slot( + uri=PHENOPACKETS.id, + name="text__id", + curie=PHENOPACKETS.curie("id"), + model_uri=PHENOPACKETS.text__id, + domain=None, + range=Optional[str], +) + +slots.utilityVariation__text = Slot( + uri=PHENOPACKETS.text, + name="utilityVariation__text", + curie=PHENOPACKETS.curie("text"), + model_uri=PHENOPACKETS.utilityVariation__text, + domain=None, + range=Optional[Union[dict, Text]], +) + +slots.utilityVariation__variationSet = Slot( + uri=PHENOPACKETS.variationSet, + name="utilityVariation__variationSet", + curie=PHENOPACKETS.curie("variationSet"), + model_uri=PHENOPACKETS.utilityVariation__variationSet, + domain=None, + range=Optional[Union[dict, VariationSet]], +) + +slots.variation__allele = Slot( + uri=PHENOPACKETS.allele, + name="variation__allele", + curie=PHENOPACKETS.curie("allele"), + model_uri=PHENOPACKETS.variation__allele, + domain=None, + range=Optional[Union[dict, Allele]], +) + +slots.variation__copyNumber = Slot( + uri=PHENOPACKETS.copyNumber, + name="variation__copyNumber", + curie=PHENOPACKETS.curie("copyNumber"), + model_uri=PHENOPACKETS.variation__copyNumber, + domain=None, + range=Optional[Union[dict, CopyNumber]], +) + +slots.variation__haplotype = Slot( + uri=PHENOPACKETS.haplotype, + name="variation__haplotype", + curie=PHENOPACKETS.curie("haplotype"), + model_uri=PHENOPACKETS.variation__haplotype, + domain=None, + range=Optional[Union[dict, Haplotype]], +) + +slots.variation__text = Slot( + uri=PHENOPACKETS.text, + name="variation__text", + curie=PHENOPACKETS.curie("text"), + model_uri=PHENOPACKETS.variation__text, + domain=None, + range=Optional[Union[dict, Text]], +) + +slots.variation__variationSet = Slot( + uri=PHENOPACKETS.variationSet, + name="variation__variationSet", + curie=PHENOPACKETS.curie("variationSet"), + model_uri=PHENOPACKETS.variation__variationSet, + domain=None, + range=Optional[Union[dict, VariationSet]], +) diff --git a/tests/test_loaders_dumpers/models/termci_schema.py b/tests/test_loaders_dumpers/models/termci_schema.py index ed47afd5..2b0388b3 100644 --- a/tests/test_loaders_dumpers/models/termci_schema.py +++ b/tests/test_loaders_dumpers/models/termci_schema.py @@ -6,30 +6,30 @@ # description: Terminology Code Index model # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.metamodelcore import empty_list, empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot from rdflib import URIRef + from linkml_runtime.utils.curienamespace import CurieNamespace -from linkml_runtime.utils.metamodelcore import URI, URIorCURIE +from linkml_runtime.utils.metamodelcore import URI, URIorCURIE, empty_dict, empty_list +from linkml_runtime.utils.yamlutils import YAMLRoot metamodel_version = "1.7.0" # Namespaces -DC = CurieNamespace('dc', 'http://purl.org/dc/elements/1.1/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -SCT = CurieNamespace('sct', 'http://snomed.info/id/') -SH = CurieNamespace('sh', 'http://www.w3.org/ns/shacl#') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') -TERMCI = CurieNamespace('termci', 'https://hotecosystem.org/termci/') +DC = CurieNamespace("dc", "http://purl.org/dc/elements/1.1/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +SCT = CurieNamespace("sct", "http://snomed.info/id/") +SH = CurieNamespace("sh", "http://www.w3.org/ns/shacl#") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") +TERMCI = CurieNamespace("termci", "https://hotecosystem.org/termci/") DEFAULT_ = TERMCI # Types + # Class references class ConceptReferenceUri(URIorCURIE): pass @@ -44,6 +44,7 @@ class ConceptReference(YAMLRoot): """ A minimal description of a class, individual, term or similar construct """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SKOS.Concept @@ -57,7 +58,9 @@ class ConceptReference(YAMLRoot): designation: Optional[str] = None definition: Optional[str] = None reference: Optional[Union[Union[str, URI], list[Union[str, URI]]]] = empty_list() - narrower_than: Optional[Union[Union[str, ConceptReferenceUri], list[Union[str, ConceptReferenceUri]]]] = empty_list() + narrower_than: Optional[Union[Union[str, ConceptReferenceUri], list[Union[str, ConceptReferenceUri]]]] = ( + empty_list() + ) def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.uri is None: @@ -91,7 +94,9 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.narrower_than = [] if not isinstance(self.narrower_than, list): self.narrower_than = [self.narrower_than] - self.narrower_than = [v if isinstance(v, ConceptReferenceUri) else ConceptReferenceUri(v) for v in self.narrower_than] + self.narrower_than = [ + v if isinstance(v, ConceptReferenceUri) else ConceptReferenceUri(v) for v in self.narrower_than + ] super().__post_init__(**kwargs) @@ -101,6 +106,7 @@ class ConceptSystem(YAMLRoot): """ A terminological resource (ontology, classification scheme, concept system, etc.) """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = SKOS.ConceptScheme @@ -113,7 +119,9 @@ class ConceptSystem(YAMLRoot): description: Optional[str] = None reference: Optional[Union[Union[str, URI], list[Union[str, URI]]]] = empty_list() root_concept: Optional[Union[Union[str, ConceptReferenceUri], list[Union[str, ConceptReferenceUri]]]] = empty_list() - contents: Optional[Union[dict[Union[str, ConceptReferenceUri], Union[dict, ConceptReference]], list[Union[dict, ConceptReference]]]] = empty_dict() + contents: Optional[ + Union[dict[Union[str, ConceptReferenceUri], Union[dict, ConceptReference]], list[Union[dict, ConceptReference]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.namespace is None: @@ -139,13 +147,17 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): self.root_concept = [] if not isinstance(self.root_concept, list): self.root_concept = [self.root_concept] - self.root_concept = [v if isinstance(v, ConceptReferenceUri) else ConceptReferenceUri(v) for v in self.root_concept] + self.root_concept = [ + v if isinstance(v, ConceptReferenceUri) else ConceptReferenceUri(v) for v in self.root_concept + ] if self.contents is None: self.contents = [] if not isinstance(self.contents, (list, dict)): self.contents = [self.contents] - self._normalize_inlined_slot(slot_name="contents", slot_type=ConceptReference, key_name="uri", inlined_as_list=True, keyed=True) + self._normalize_inlined_slot( + slot_name="contents", slot_type=ConceptReference, key_name="uri", inlined_as_list=True, keyed=True + ) super().__post_init__(**kwargs) @@ -155,6 +167,7 @@ class Package(YAMLRoot): """ A collection of ConceptSystems """ + _inherited_slots: ClassVar[list[str]] = [] class_class_uri: ClassVar[URIRef] = TERMCI.Package @@ -162,14 +175,18 @@ class Package(YAMLRoot): class_name: ClassVar[str] = "Package" class_model_uri: ClassVar[URIRef] = TERMCI.Package - system: Optional[Union[dict[Union[str, ConceptSystemNamespace], Union[dict, ConceptSystem]], list[Union[dict, ConceptSystem]]]] = empty_dict() + system: Optional[ + Union[dict[Union[str, ConceptSystemNamespace], Union[dict, ConceptSystem]], list[Union[dict, ConceptSystem]]] + ] = empty_dict() def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): if self.system is None: self.system = [] if not isinstance(self.system, (list, dict)): self.system = [self.system] - self._normalize_inlined_slot(slot_name="system", slot_type=ConceptSystem, key_name="namespace", inlined_as_list=True, keyed=True) + self._normalize_inlined_slot( + slot_name="system", slot_type=ConceptSystem, key_name="namespace", inlined_as_list=True, keyed=True + ) super().__post_init__(**kwargs) @@ -178,4 +195,3 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): # Slots - diff --git a/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py b/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py index 9e6f3300..0c04a3ad 100644 --- a/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py +++ b/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py @@ -1,97 +1,96 @@ -import os -import unittest import json import logging +import os +import unittest from jsonasobj2 import as_json_obj -from linkml_runtime.dumpers import json_dumper, yaml_dumper -from linkml_runtime.loaders import yaml_loader +from linkml_runtime.dumpers import csv_dumper, json_dumper, tsv_dumper, yaml_dumper +from linkml_runtime.loaders import csv_loader, tsv_loader, yaml_loader from linkml_runtime.utils.formatutils import remove_empty_items from linkml_runtime.utils.schemaview import SchemaView -from linkml_runtime.dumpers import csv_dumper, tsv_dumper -from linkml_runtime.loaders import csv_loader, tsv_loader from linkml_runtime.utils.yamlutils import as_json_object -from tests.test_loaders_dumpers.models.books_normalized import Author, Review, Shop, Book, BookSeries +from tests.test_loaders_dumpers.models.books_normalized import Author, Book, BookSeries, Review, Shop logger = logging.getLogger(__name__) ROOT = os.path.abspath(os.path.dirname(__file__)) -INPUT_DIR = os.path.join(ROOT, 'input') -OUTPUT_DIR = os.path.join(ROOT, 'output') -MODEL_DIR = os.path.join(ROOT, 'models') +INPUT_DIR = os.path.join(ROOT, "input") +OUTPUT_DIR = os.path.join(ROOT, "output") +MODEL_DIR = os.path.join(ROOT, "models") + +SCHEMA = os.path.join(MODEL_DIR, "books_normalized.yaml") +DATA = os.path.join(INPUT_DIR, "books_normalized_01.yaml") +DATA2 = os.path.join(INPUT_DIR, "books_normalized_02.yaml") +OUTPUT = os.path.join(OUTPUT_DIR, "books_flattened.tsv") +OUTPUT2 = os.path.join(OUTPUT_DIR, "books_flattened_02.tsv") -SCHEMA = os.path.join(MODEL_DIR, 'books_normalized.yaml') -DATA = os.path.join(INPUT_DIR, 'books_normalized_01.yaml') -DATA2 = os.path.join(INPUT_DIR, 'books_normalized_02.yaml') -OUTPUT = os.path.join(OUTPUT_DIR, 'books_flattened.tsv') -OUTPUT2 = os.path.join(OUTPUT_DIR, 'books_flattened_02.tsv') def _json(obj) -> str: - return json.dumps(obj, indent=' ', sort_keys=True) + return json.dumps(obj, indent=" ", sort_keys=True) class CsvAndTsvGenTestCase(unittest.TestCase): def test_object_model(self): - book = Book(id='B1', genres=['fantasy'], creator={}) + book = Book(id="B1", genres=["fantasy"], creator={}) logger.debug(as_json_obj(book.genres[0])) - assert str(book.genres[0]) == 'fantasy' - assert book.genres[0].code.text == 'fantasy' + assert str(book.genres[0]) == "fantasy" + assert book.genres[0].code.text == "fantasy" processed = remove_empty_items(book.genres) - assert processed[0] == 'fantasy' - series = BookSeries(id='S1', creator=Author(name="Q. Writer"), reviews=[Review(rating=5)]) + assert processed[0] == "fantasy" + series = BookSeries(id="S1", creator=Author(name="Q. Writer"), reviews=[Review(rating=5)]) series.books.append(book) schemaview = SchemaView(SCHEMA) shop = Shop() shop.all_book_series.append(series) - csvstr = csv_dumper.dumps(shop, index_slot='all_book_series', schemaview=schemaview) + csvstr = csv_dumper.dumps(shop, index_slot="all_book_series", schemaview=schemaview) assert "," in csvstr assert "\t" not in csvstr - tsvstr = tsv_dumper.dumps(shop, index_slot='all_book_series', schemaview=schemaview) + tsvstr = tsv_dumper.dumps(shop, index_slot="all_book_series", schemaview=schemaview) assert "\t" in tsvstr def test_csvgen_roundtrip(self): schemaview = SchemaView(SCHEMA) data = yaml_loader.load(DATA, target_class=Shop) - csv_dumper.dump(data, to_file=OUTPUT, index_slot='all_book_series', schemaview=schemaview) - roundtrip = csv_loader.load(OUTPUT, target_class=Shop, index_slot='all_book_series', schemaview=schemaview) + csv_dumper.dump(data, to_file=OUTPUT, index_slot="all_book_series", schemaview=schemaview) + roundtrip = csv_loader.load(OUTPUT, target_class=Shop, index_slot="all_book_series", schemaview=schemaview) logger.debug(json_dumper.dumps(roundtrip)) - logger.debug(f'COMPARE 1: {roundtrip}') - logger.debug(f'COMPARE 2: {data}') + logger.debug(f"COMPARE 1: {roundtrip}") + logger.debug(f"COMPARE 2: {data}") assert roundtrip == data def test_csvgen_roundtrip_to_dict(self): schemaview = SchemaView(SCHEMA) data = yaml_loader.load(DATA, target_class=Shop) - csv_dumper.dump(data, to_file=OUTPUT, index_slot='all_book_series', schemaview=schemaview) - roundtrip = csv_loader.load_as_dict(OUTPUT, index_slot='all_book_series', schemaview=schemaview) + csv_dumper.dump(data, to_file=OUTPUT, index_slot="all_book_series", schemaview=schemaview) + roundtrip = csv_loader.load_as_dict(OUTPUT, index_slot="all_book_series", schemaview=schemaview) assert roundtrip == json_dumper.to_dict(data) def test_tsvgen_roundtrip(self): schemaview = SchemaView(SCHEMA) data = yaml_loader.load(DATA, target_class=Shop) - tsv_dumper.dump(data, to_file=OUTPUT, index_slot='all_book_series', schemaview=schemaview) - roundtrip = tsv_loader.load(OUTPUT, target_class=Shop, index_slot='all_book_series', schemaview=schemaview) + tsv_dumper.dump(data, to_file=OUTPUT, index_slot="all_book_series", schemaview=schemaview) + roundtrip = tsv_loader.load(OUTPUT, target_class=Shop, index_slot="all_book_series", schemaview=schemaview) assert roundtrip == data def test_tsvgen_roundtrip_to_dict(self): schemaview = SchemaView(SCHEMA) data = yaml_loader.load(DATA, target_class=Shop) - tsv_dumper.dump(data, to_file=OUTPUT, index_slot='all_book_series', schemaview=schemaview) - roundtrip = tsv_loader.load_as_dict(OUTPUT, index_slot='all_book_series', schemaview=schemaview) + tsv_dumper.dump(data, to_file=OUTPUT, index_slot="all_book_series", schemaview=schemaview) + roundtrip = tsv_loader.load_as_dict(OUTPUT, index_slot="all_book_series", schemaview=schemaview) assert roundtrip == json_dumper.to_dict(data) def test_csvgen_unroundtrippable(self): schemaview = SchemaView(SCHEMA) - #schema = YAMLGenerator(SCHEMA).schema + # schema = YAMLGenerator(SCHEMA).schema data = yaml_loader.load(DATA2, target_class=Shop) logger.debug(data.all_book_series[0]) logger.debug(data.all_book_series[0].genres[0]) - assert str(data.all_book_series[0].genres[0]) == 'fantasy' + assert str(data.all_book_series[0].genres[0]) == "fantasy" logger.debug(yaml_dumper.dumps(data)) logger.debug(json_dumper.dumps(data)) processed = remove_empty_items(data) @@ -99,30 +98,24 @@ def test_csvgen_unroundtrippable(self): asj = as_json_object(processed, None) logger.debug(f'ASJ {asj["all_book_series"]}') reconstituted_json = json.loads(json_dumper.dumps(data)) - s0 = reconstituted_json['all_book_series'][0] + s0 = reconstituted_json["all_book_series"][0] logger.debug(s0) logger.debug(json_dumper.dumps(data)) - #logger.debug(csv_dumper.dumps(data, index_slot='all_book_series', schema=schema)) - csv_dumper.dump(data, to_file=OUTPUT2, index_slot='all_book_series', schemaview=schemaview) - #assert False - roundtrip = csv_loader.load(OUTPUT2, target_class=Shop, index_slot='all_book_series', schemaview=schemaview) + # logger.debug(csv_dumper.dumps(data, index_slot='all_book_series', schema=schema)) + csv_dumper.dump(data, to_file=OUTPUT2, index_slot="all_book_series", schemaview=schemaview) + # assert False + roundtrip = csv_loader.load(OUTPUT2, target_class=Shop, index_slot="all_book_series", schemaview=schemaview) logger.debug(json_dumper.dumps(roundtrip)) assert roundtrip == data def test_tsvgen_unroundtrippable(self): schemaview = SchemaView(SCHEMA) data = yaml_loader.load(DATA2, target_class=Shop) - assert str(data.all_book_series[0].genres[0]) == 'fantasy' - tsv_dumper.dump(data, to_file=OUTPUT2, index_slot='all_book_series', schemaview=schemaview) - roundtrip = tsv_loader.load(OUTPUT2, target_class=Shop, index_slot='all_book_series', schemaview=schemaview) + assert str(data.all_book_series[0].genres[0]) == "fantasy" + tsv_dumper.dump(data, to_file=OUTPUT2, index_slot="all_book_series", schemaview=schemaview) + roundtrip = tsv_loader.load(OUTPUT2, target_class=Shop, index_slot="all_book_series", schemaview=schemaview) assert roundtrip == data - - - - - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_dumpers.py b/tests/test_loaders_dumpers/test_dumpers.py index 35b1526e..d64c6514 100644 --- a/tests/test_loaders_dumpers/test_dumpers.py +++ b/tests/test_loaders_dumpers/test_dumpers.py @@ -2,13 +2,20 @@ import unittest from typing import cast -from rdflib import Namespace, SKOS, Literal +from rdflib import SKOS, Literal, Namespace -from linkml_runtime.dumpers import yaml_dumper, json_dumper, rdf_dumper +from linkml_runtime.dumpers import json_dumper, rdf_dumper, yaml_dumper from linkml_runtime.utils.yamlutils import as_json_object from tests.support.clicktestcase import ClickTestCase -from tests.test_loaders_dumpers import LD_11_DIR, LD_11_SSL_SVR, LD_11_SVR, HTTP_TEST_PORT, HTTPS_TEST_PORT, \ - GITHUB_LD10_CONTEXT, GITHUB_LD11_CONTEXT +from tests.test_loaders_dumpers import ( + GITHUB_LD10_CONTEXT, + GITHUB_LD11_CONTEXT, + HTTP_TEST_PORT, + HTTPS_TEST_PORT, + LD_11_DIR, + LD_11_SSL_SVR, + LD_11_SVR, +) from tests.test_loaders_dumpers.loaderdumpertestcase import LoaderDumperTestCase from tests.test_loaders_dumpers.models.termci_schema import ConceptReference, ConceptSystem, Package @@ -21,72 +28,93 @@ class DumpersTestCase(LoaderDumperTestCase): @classmethod def setUpClass(cls) -> None: - """ Generate a small sample TermCI instance for testing purposes """ + """Generate a small sample TermCI instance for testing purposes""" LoaderDumperTestCase.setUpClass() - e1 = ConceptReference(OBO.NCI_C147796, code="C147796", defined_in=OBO, - designation="TSCYC - Being Frightened of Men", - definition="Trauma Symptom Checklist for Young Children (TSCYC) Please indicate how often" - " the child has done, felt, or experienced each of the following things in " - "the last month: Being frightened of men.", - narrower_than=OBO.NCI_C147557, reference=OBO.NCI_C147796) - e2 = ConceptReference(OBO.NCI_C147557, code="C147557", defined_in=OBO, - designation="TSCYC Questionnaire Question", - definition="A question associated with the TSCYC questionnaire.", - narrower_than=OBO.NCI_C91102) + e1 = ConceptReference( + OBO.NCI_C147796, + code="C147796", + defined_in=OBO, + designation="TSCYC - Being Frightened of Men", + definition="Trauma Symptom Checklist for Young Children (TSCYC) Please indicate how often" + " the child has done, felt, or experienced each of the following things in " + "the last month: Being frightened of men.", + narrower_than=OBO.NCI_C147557, + reference=OBO.NCI_C147796, + ) + e2 = ConceptReference( + OBO.NCI_C147557, + code="C147557", + defined_in=OBO, + designation="TSCYC Questionnaire Question", + definition="A question associated with the TSCYC questionnaire.", + narrower_than=OBO.NCI_C91102, + ) c1 = ConceptSystem(OBO, "OBO", contents=[e1, e2]) cls.test_package = Package([c1]) def test_yaml_dumper(self): - """ Test the yaml emitter """ + """Test the yaml emitter""" # TODO: Once this is entered into the BiolinkML test package, compare this to input/obo_test.yaml - self.dump_test('obo_sample.yaml', lambda out_fname: yaml_dumper.dump(self.test_package, out_fname)) - self.dumps_test('obo_sample.yaml', lambda: yaml_dumper.dumps(self.test_package)) + self.dump_test("obo_sample.yaml", lambda out_fname: yaml_dumper.dump(self.test_package, out_fname)) + self.dumps_test("obo_sample.yaml", lambda: yaml_dumper.dumps(self.test_package)) def test_json_dumper(self): - """ Test the json emitter """ + """Test the json emitter""" # TODO: Same as test_yaml_dumper - self.dump_test('obo_sample.json', lambda out_fname: json_dumper.dump(self.test_package, out_fname)) + self.dump_test("obo_sample.json", lambda out_fname: json_dumper.dump(self.test_package, out_fname)) obo_json_obj = cast(Package, as_json_object(self.test_package)) self.assertEqual(OBO, obo_json_obj.system[0].namespace) - self.assertEqual('C147796', obo_json_obj.system[0].contents[0].code) - - self.dumps_test('obo_sample.json', lambda: json_dumper.dumps(self.test_package)) - self.dump_test('obo_sample_context.json', - lambda out_fname: json_dumper.dump(self.test_package, out_fname, - GITHUB_LD10_CONTEXT + 'termci_schema.context.jsonld')) - self.dumps_test('obo_sample_context.json', - lambda: json_dumper.dumps(self.test_package, - GITHUB_LD11_CONTEXT + 'termci_schema_inlined.context.jsonld')) + self.assertEqual("C147796", obo_json_obj.system[0].contents[0].code) + + self.dumps_test("obo_sample.json", lambda: json_dumper.dumps(self.test_package)) + self.dump_test( + "obo_sample_context.json", + lambda out_fname: json_dumper.dump( + self.test_package, out_fname, GITHUB_LD10_CONTEXT + "termci_schema.context.jsonld" + ), + ) + self.dumps_test( + "obo_sample_context.json", + lambda: json_dumper.dumps(self.test_package, GITHUB_LD11_CONTEXT + "termci_schema_inlined.context.jsonld"), + ) @unittest.skipIf(True, "This needs an enhanced (https://github.com/hsolbrig/pyld) version of pyld") def test_rdf_dumper(self): - """ Test the rdf dumper """ - contexts = os.path.join(LD_11_DIR, 'termci_schema_inlined.context.jsonld') - self.dump_test('obo_sample.ttl', lambda out_file: rdf_dumper.dump(self.test_package, out_file, contexts), - comparator=ClickTestCase.rdf_comparator) + """Test the rdf dumper""" + contexts = os.path.join(LD_11_DIR, "termci_schema_inlined.context.jsonld") + self.dump_test( + "obo_sample.ttl", + lambda out_file: rdf_dumper.dump(self.test_package, out_file, contexts), + comparator=ClickTestCase.rdf_comparator, + ) g = rdf_dumper.as_rdf_graph(self.test_package, contexts) - self.assertIn(OBO[''], g.subjects()) + self.assertIn(OBO[""], g.subjects()) self.assertIn(NCIT.C147796, g.subjects()) - self.assertIn(Literal('C147796'), g.objects(NCIT.C147796, SKOS.notation)) + self.assertIn(Literal("C147796"), g.objects(NCIT.C147796, SKOS.notation)) - self.dumps_test('obo_sample.ttl', lambda: rdf_dumper.dumps(self.test_package, contexts), - comparator=ClickTestCase.rdf_comparator) + self.dumps_test( + "obo_sample.ttl", + lambda: rdf_dumper.dumps(self.test_package, contexts), + comparator=ClickTestCase.rdf_comparator, + ) # Build a vanilla jsonld image for subsequent testing - fname = 'obo_sample.jsonld' - self.dump_test(fname, lambda out_file: rdf_dumper.dump(self.test_package, out_file, contexts, fmt='json-ld'), - comparator=lambda e, a: ClickTestCase.rdf_comparator(e, a, fmt='json-ld')) - with open(self.env.expected_path('dump', fname)) as f: + fname = "obo_sample.jsonld" + self.dump_test( + fname, + lambda out_file: rdf_dumper.dump(self.test_package, out_file, contexts, fmt="json-ld"), + comparator=lambda e, a: ClickTestCase.rdf_comparator(e, a, fmt="json-ld"), + ) + with open(self.env.expected_path("dump", fname)) as f: txt = f.read() - with open(self.env.input_path('obo_sample.jsonld'), 'w') as f: + with open(self.env.input_path("obo_sample.jsonld"), "w") as f: f.write(txt) - @unittest.skip("Waiting until PyLD learns to handle relative context URI's") def test_nested_contexts(self): - """ Test JSON-LD with fully nested contexts """ + """Test JSON-LD with fully nested contexts""" context_servers = [] for possible_server in [LD_11_SVR, LD_11_SSL_SVR]: @@ -95,15 +123,18 @@ def test_nested_contexts(self): context_servers.append(svr) if not context_servers: - raise unittest.SkipTest(f"*****> Nested contexts test skipped - no servers found on sockets " - f"{HTTP_TEST_PORT} or {HTTPS_TEST_PORT}") + raise unittest.SkipTest( + f"*****> Nested contexts test skipped - no servers found on sockets " + f"{HTTP_TEST_PORT} or {HTTPS_TEST_PORT}" + ) for context_base in context_servers: - nested_context = context_base + 'Package.context.jsonld' - self.dump_test('obo_sample_nested.ttl', lambda out_file: rdf_dumper.dump(self.test_package, out_file, - nested_context)) - self.dumps_test('obo_sample_nested.ttl', lambda: rdf_dumper.dumps(self.test_package, nested_context)) + nested_context = context_base + "Package.context.jsonld" + self.dump_test( + "obo_sample_nested.ttl", lambda out_file: rdf_dumper.dump(self.test_package, out_file, nested_context) + ) + self.dumps_test("obo_sample_nested.ttl", lambda: rdf_dumper.dumps(self.test_package, nested_context)) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_dumpers_pydantic.py b/tests/test_loaders_dumpers/test_dumpers_pydantic.py index 3ff83ba1..2d79427b 100644 --- a/tests/test_loaders_dumpers/test_dumpers_pydantic.py +++ b/tests/test_loaders_dumpers/test_dumpers_pydantic.py @@ -2,11 +2,11 @@ import yaml -from linkml_runtime.dumpers import yaml_dumper, json_dumper +from linkml_runtime.dumpers import json_dumper, yaml_dumper +from linkml_runtime.utils.formatutils import remove_empty_items from tests.test_loaders_dumpers.loaderdumpertestcase import LoaderDumperTestCase -from tests.test_loaders_dumpers.models.books_normalized_pydantic import Book, BookSeries, Author +from tests.test_loaders_dumpers.models.books_normalized_pydantic import Author, Book, BookSeries from tests.test_loaders_dumpers.models.kitchen_sink_pydantic import BirthEvent, Person -from linkml_runtime.utils.formatutils import remove_empty_items class PydanticDumpersTestCase(LoaderDumperTestCase): @@ -14,62 +14,59 @@ class PydanticDumpersTestCase(LoaderDumperTestCase): @classmethod def setUpClass(cls) -> None: - """ Generate a small sample Books instance for testing purposes """ + """Generate a small sample Books instance for testing purposes""" LoaderDumperTestCase.setUpClass() - b1 = Book(name='Fellowship of the Ring', id="S001.1", price="5.99", summary="Hobbits") - b2 = Book(name='The Two Towers', id="S001.2", price="5.99", summary="More hobbits") - b3 = Book(name='Return of the King', id="S001.3", price="6.99", summary="Yet more hobbits") - jrr = Author(name='JRR Tolkein', from_country='England') - cls.bookseries = BookSeries(name='Lord of the Rings', id="S001", genres=["fantasy"], creator=jrr, books=[b1, b2, b3]) + b1 = Book(name="Fellowship of the Ring", id="S001.1", price="5.99", summary="Hobbits") + b2 = Book(name="The Two Towers", id="S001.2", price="5.99", summary="More hobbits") + b3 = Book(name="Return of the King", id="S001.3", price="6.99", summary="Yet more hobbits") + jrr = Author(name="JRR Tolkein", from_country="England") + cls.bookseries = BookSeries( + name="Lord of the Rings", id="S001", genres=["fantasy"], creator=jrr, books=[b1, b2, b3] + ) def test_yaml_dumper(self): - """ Test the yaml emitter """ - self.dump_test('book_series_lotr.yaml', lambda out_fname: yaml_dumper.dump(self.bookseries, out_fname)) - self.dumps_test('book_series_lotr.yaml', lambda: yaml_dumper.dumps(self.bookseries)) + """Test the yaml emitter""" + self.dump_test("book_series_lotr.yaml", lambda out_fname: yaml_dumper.dump(self.bookseries, out_fname)) + self.dumps_test("book_series_lotr.yaml", lambda: yaml_dumper.dumps(self.bookseries)) # test contents of yaml file with cleaned dict made from bookseries instance in setup - with open(self.env.input_path('book_series_lotr.yaml')) as f: + with open(self.env.input_path("book_series_lotr.yaml")) as f: data = yaml.safe_load(f) # explicitly confirm that unset fields aren't written to the file for i in range(3): - 'genres' not in data['books'][i].keys() - 'inStock' not in data['books'][i].keys() - 'creator' not in data['books'][i].keys() + "genres" not in data["books"][i].keys() + "inStock" not in data["books"][i].keys() + "creator" not in data["books"][i].keys() self.assertEqual(data, remove_empty_items(self.bookseries.model_dump())) - def test_json_dumper(self): - """ Test the json emitter """ - self.dump_test('book_series_lotr.json', lambda out_fname: json_dumper.dump(self.bookseries, out_fname)) - self.dumps_test('book_series_lotr.json', lambda: json_dumper.dumps(self.bookseries)) + """Test the json emitter""" + self.dump_test("book_series_lotr.json", lambda out_fname: json_dumper.dump(self.bookseries, out_fname)) + self.dumps_test("book_series_lotr.json", lambda: json_dumper.dumps(self.bookseries)) # test contents of json file with cleaned dict made from bookseries instance in setup - with open(self.env.input_path('book_series_lotr.json')) as f: + with open(self.env.input_path("book_series_lotr.json")) as f: data = json.load(f) # explicitly confirm that unset fields aren't written to the file for i in range(3): - 'genres' not in data['books'][i].keys() - 'inStock' not in data['books'][i].keys() - 'creator' not in data['books'][i].keys() + "genres" not in data["books"][i].keys() + "inStock" not in data["books"][i].keys() + "creator" not in data["books"][i].keys() self.assertEqual(data, remove_empty_items(self.bookseries.model_dump())) - + class PydanticDumpersDateTestCase(LoaderDumperTestCase): @classmethod def setUpClass(cls) -> None: - """ Generate an example with a date for testing purposes """ + """Generate an example with a date for testing purposes""" LoaderDumperTestCase.setUpClass() b1 = BirthEvent(started_at_time="2021-01-01", ended_at_time="2021-01-02") - - cls.person = Person( - id="P01", - name='John Doe', - has_birth_event=b1 - ) + + cls.person = Person(id="P01", name="John Doe", has_birth_event=b1) def test_yaml_dumper(self): - """ Test the yaml emitter """ + """Test the yaml emitter""" # with open(self.env.input_path('kitchen_sink_person_01.yaml'), 'w', encoding='utf-8') as f: # # write the yaml file # f.write(yaml_dumper.dumps(self.person)) @@ -77,10 +74,10 @@ def test_yaml_dumper(self): # # write the json file # f.write(json_dumper.dumps(self.person, inject_type=False)) - self.dump_test('kitchen_sink_person_01.yaml', lambda out_fname: yaml_dumper.dump(self.person, out_fname)) - self.dumps_test('kitchen_sink_person_01.yaml', lambda: yaml_dumper.dumps(self.person)) + self.dump_test("kitchen_sink_person_01.yaml", lambda out_fname: yaml_dumper.dump(self.person, out_fname)) + self.dumps_test("kitchen_sink_person_01.yaml", lambda: yaml_dumper.dumps(self.person)) def test_json_dumper(self): - """ Test the json emitter """ - self.dump_test('kitchen_sink_person_01.json', lambda out_fname: json_dumper.dump(self.person, out_fname)) - self.dumps_test('kitchen_sink_person_01.json', lambda: json_dumper.dumps(self.person)) + """Test the json emitter""" + self.dump_test("kitchen_sink_person_01.json", lambda out_fname: json_dumper.dump(self.person, out_fname)) + self.dumps_test("kitchen_sink_person_01.json", lambda: json_dumper.dumps(self.person)) diff --git a/tests/test_loaders_dumpers/test_enum.py b/tests/test_loaders_dumpers/test_enum.py index ed47a9e8..0f3c81a1 100644 --- a/tests/test_loaders_dumpers/test_enum.py +++ b/tests/test_loaders_dumpers/test_enum.py @@ -1,9 +1,10 @@ -import unittest import json +import unittest + import yaml -from linkml_runtime.loaders import json_loader from linkml_runtime.dumpers import json_dumper, yaml_dumper +from linkml_runtime.loaders import json_loader from tests.test_loaders_dumpers.models.enum_model import Organism, StateEnum @@ -16,28 +17,23 @@ def test_enum(self): * https://github.com/linkml/linkml/issues/337 * https://github.com/linkml/linkml/issues/119 """ - i = Organism(state='LIVING') + i = Organism(state="LIVING") print(i) print(i.state) print(i.state.code) print(i.state.code.text) print(type(i.state)) print(StateEnum.LIVING) - assert str(i.state) == 'LIVING' + assert str(i.state) == "LIVING" assert i.state.code == StateEnum.LIVING obj = json.loads(json_dumper.dumps(i)) - assert obj['state'] == 'LIVING' + assert obj["state"] == "LIVING" obj = yaml.safe_load(yaml_dumper.dumps(i)) - assert obj['state'] == 'LIVING' + assert obj["state"] == "LIVING" reconstituted = json_loader.loads(json_dumper.dumps(i), target_class=Organism) - print(f'RECONSTITUTED = {reconstituted}') + print(f"RECONSTITUTED = {reconstituted}") assert reconstituted.state.code == StateEnum.LIVING - - - - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_issue_429.py b/tests/test_loaders_dumpers/test_issue_429.py index b5b95370..1c33b5b6 100644 --- a/tests/test_loaders_dumpers/test_issue_429.py +++ b/tests/test_loaders_dumpers/test_issue_429.py @@ -1,8 +1,9 @@ import os import unittest -from rdflib import Graph, Literal -from rdflib import Namespace + +from rdflib import Graph, Literal, Namespace from rdflib.namespace import RDF + from linkml_runtime.dumpers import rdflib_dumper from linkml_runtime.loaders import yaml_loader from linkml_runtime.utils.schemaview import SchemaView @@ -11,13 +12,13 @@ class RdfLibPrefixTestCase(unittest.TestCase): - SCHEMA = os.path.join(INPUT_DIR, 'personinfo_test_issue_429.yaml') - DATA = os.path.join(INPUT_DIR, 'example_personinfo_test_issue_429_data.yaml') - OUT = os.path.join(OUTPUT_DIR, 'example_personinfo_test_issue_429_data.ttl') + SCHEMA = os.path.join(INPUT_DIR, "personinfo_test_issue_429.yaml") + DATA = os.path.join(INPUT_DIR, "example_personinfo_test_issue_429_data.yaml") + OUT = os.path.join(OUTPUT_DIR, "example_personinfo_test_issue_429_data.ttl") - ORCID = Namespace('https://orcid.org/') - personinfo = Namespace('https://w3id.org/linkml/examples/personinfo/') - SDO = Namespace('http://schema.org/') + ORCID = Namespace("https://orcid.org/") + personinfo = Namespace("https://w3id.org/linkml/examples/personinfo/") + SDO = Namespace("http://schema.org/") def setUp(self): self.g = self.create_rdf_output() @@ -27,26 +28,26 @@ def create_rdf_output(self): container = yaml_loader.load(self.DATA, target_class=Container) rdflib_dumper.dump(container, schemaview=view, to_file=self.OUT) g = Graph() - g.parse(self.OUT, format='ttl') + g.parse(self.OUT, format="ttl") return g def test_rdf_output(self): - self.assertIn((self.ORCID['1234'], RDF.type, self.SDO.Person), self.g) - self.assertIn((self.ORCID['1234'], self.personinfo.full_name, Literal("Clark Kent")), self.g) - self.assertIn((self.ORCID['1234'], self.personinfo.age, Literal("32")), self.g) - self.assertIn((self.ORCID['1234'], self.personinfo.phone, Literal("555-555-5555")), self.g) - self.assertIn((self.ORCID['4567'], RDF.type, self.SDO.Person), self.g) - self.assertIn((self.ORCID['4567'], self.personinfo.full_name, Literal("Lois Lane")), self.g) - self.assertIn((self.ORCID['4567'], self.personinfo.age, Literal("33")), self.g) - self.assertIn((self.ORCID['4567'], self.personinfo.phone, Literal("555-555-5555")), self.g) + self.assertIn((self.ORCID["1234"], RDF.type, self.SDO.Person), self.g) + self.assertIn((self.ORCID["1234"], self.personinfo.full_name, Literal("Clark Kent")), self.g) + self.assertIn((self.ORCID["1234"], self.personinfo.age, Literal("32")), self.g) + self.assertIn((self.ORCID["1234"], self.personinfo.phone, Literal("555-555-5555")), self.g) + self.assertIn((self.ORCID["4567"], RDF.type, self.SDO.Person), self.g) + self.assertIn((self.ORCID["4567"], self.personinfo.full_name, Literal("Lois Lane")), self.g) + self.assertIn((self.ORCID["4567"], self.personinfo.age, Literal("33")), self.g) + self.assertIn((self.ORCID["4567"], self.personinfo.phone, Literal("555-555-5555")), self.g) def test_output_prefixes(self): - with open(self.OUT, encoding='UTF-8') as file: + with open(self.OUT, encoding="UTF-8") as file: file_string = file.read() - prefixes = ['prefix ORCID:', 'prefix personinfo:', 'prefix sdo:', 'sdo:Person', 'personinfo:age', 'ORCID:1234'] + prefixes = ["prefix ORCID:", "prefix personinfo:", "prefix sdo:", "sdo:Person", "personinfo:age", "ORCID:1234"] for prefix in prefixes: - assert(prefix in file_string) + assert prefix in file_string -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_loaders.py b/tests/test_loaders_dumpers/test_loaders.py index c5f7ee0f..4a8af311 100644 --- a/tests/test_loaders_dumpers/test_loaders.py +++ b/tests/test_loaders_dumpers/test_loaders.py @@ -1,12 +1,13 @@ import os import unittest -from typing import Union, TextIO, Optional from pathlib import Path +from typing import Optional, TextIO, Union + from hbreader import FileInfo -from linkml_runtime.loaders import yaml_loader, json_loader, rdf_loader, RDFLoader +from linkml_runtime.loaders import RDFLoader, json_loader, rdf_loader, yaml_loader from linkml_runtime.utils.yamlutils import YAMLRoot -from tests.test_loaders_dumpers import LD_11_SVR, LD_11_SSL_SVR, LD_11_DIR +from tests.test_loaders_dumpers import LD_11_DIR, LD_11_SSL_SVR, LD_11_SVR from tests.test_loaders_dumpers.environment import env from tests.test_loaders_dumpers.loaderdumpertestcase import LoaderDumperTestCase from tests.test_loaders_dumpers.models.termci_schema import Package @@ -22,56 +23,70 @@ def setUpClass(cls) -> None: cls.context_server = LD_11_DIR def test_yaml_loader(self): - """ Load obo_sample.yaml, emit obo_sample_yaml.yaml and compare to obo_sample_output.yaml """ - self.loader_test('obo_sample.yaml', Package, yaml_loader) + """Load obo_sample.yaml, emit obo_sample_yaml.yaml and compare to obo_sample_output.yaml""" + self.loader_test("obo_sample.yaml", Package, yaml_loader) def test_json_loader_path(self): - """ Load obo_sample.json, emit obo_sample_json.yaml and check the results """ + """Load obo_sample.json, emit obo_sample_json.yaml and check the results""" REPO_ROOT = Path(__file__).parent.parent.parent - path = REPO_ROOT / "tests" / "test_loaders_dumpers" / "input" / "obo_sample.json" + path = REPO_ROOT / "tests" / "test_loaders_dumpers" / "input" / "obo_sample.json" data = json_loader.load(Path(path), Package, base_dir=self.env.indir) assert isinstance(data, Package) assert "system" in data def test_json_loader(self): - """ Load obo_sample.json, emit obo_sample_json.yaml and check the results """ - self.loader_test('obo_sample.json', Package, json_loader) + """Load obo_sample.json, emit obo_sample_json.yaml and check the results""" + self.loader_test("obo_sample.json", Package, json_loader) def test_json_load_to_dict(self): - data = json_loader.load_as_dict('obo_sample.json', base_dir=self.env.indir) + data = json_loader.load_as_dict("obo_sample.json", base_dir=self.env.indir) assert isinstance(data, dict) assert "system" in data def test_yaml_load_to_dict(self): - data = yaml_loader.load_as_dict('obo_sample.yaml', base_dir=self.env.indir) + data = yaml_loader.load_as_dict("obo_sample.yaml", base_dir=self.env.indir) assert isinstance(data, dict) assert "system" in data @unittest.skipIf(True, "This test will not work until https://github.com/digitalbazaar/pyld/issues/149 is fixed") def test_rdf_loader(self): - """ Load obo_sample.ttl, emit obo_sample_ttl.yaml and check the results - Load obo_sample.jsonld, emit obo_sample_jsonld.yaml and check the results + """Load obo_sample.ttl, emit obo_sample_ttl.yaml and check the results + Load obo_sample.jsonld, emit obo_sample_jsonld.yaml and check the results """ if self.context_server == LD_11_DIR: raise unittest.SkipTest("*****> Loading skipped until JSON-LD processor can handle non-http files") - contexts = os.path.join(self.context_server, 'termci_schema_inlined.context.jsonld') - fmt = 'turtle' + contexts = os.path.join(self.context_server, "termci_schema_inlined.context.jsonld") + fmt = "turtle" class RDFLoaderWrapper(RDFLoader): - def load(self, source: Union[str, dict, TextIO], target_class: type[YAMLRoot], *, - base_dir: Optional[str] = None, metadata: Optional[FileInfo] = None, **_) -> YAMLRoot: - return rdf_loader.load(source, target_class, base_dir=LoadersUnitTest.env.indir, fmt=fmt, - metadata=metadata, contexts=contexts) - - def loads(self, source: str, target_class: type[YAMLRoot], *, metadata: Optional[FileInfo] = None, **_) \ - -> YAMLRoot: + def load( + self, + source: Union[str, dict, TextIO], + target_class: type[YAMLRoot], + *, + base_dir: Optional[str] = None, + metadata: Optional[FileInfo] = None, + **_, + ) -> YAMLRoot: + return rdf_loader.load( + source, + target_class, + base_dir=LoadersUnitTest.env.indir, + fmt=fmt, + metadata=metadata, + contexts=contexts, + ) + + def loads( + self, source: str, target_class: type[YAMLRoot], *, metadata: Optional[FileInfo] = None, **_ + ) -> YAMLRoot: return rdf_loader.loads(source, target_class, contexts=contexts, fmt=fmt, metadata=metadata) - self.loader_test('obo_sample.ttl', Package, RDFLoaderWrapper()) - fmt = 'json-ld' - self.loader_test('obo_sample.jsonld', Package, RDFLoaderWrapper()) + self.loader_test("obo_sample.ttl", Package, RDFLoaderWrapper()) + fmt = "json-ld" + self.loader_test("obo_sample.jsonld", Package, RDFLoaderWrapper()) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_loaders_dumpers.py b/tests/test_loaders_dumpers/test_loaders_dumpers.py index 2ecde131..68f790c1 100644 --- a/tests/test_loaders_dumpers/test_loaders_dumpers.py +++ b/tests/test_loaders_dumpers/test_loaders_dumpers.py @@ -1,47 +1,45 @@ import json +import logging import os import unittest -import logging from decimal import Decimal import yaml -from rdflib import Graph -from rdflib import Namespace +from rdflib import Graph, Namespace -from linkml_runtime.loaders import json_loader -from linkml_runtime.dumpers import rdflib_dumper, yaml_dumper, json_dumper -from linkml_runtime.loaders import yaml_loader -from linkml_runtime.loaders import rdflib_loader +from linkml_runtime.dumpers import json_dumper, rdflib_dumper, yaml_dumper +from linkml_runtime.loaders import json_loader, rdflib_loader, yaml_loader from linkml_runtime.utils.schemaview import SchemaView from tests.test_loaders_dumpers import INPUT_DIR, OUTPUT_DIR -from tests.test_loaders_dumpers.models.personinfo import Container, Person from tests.test_loaders_dumpers.models.node_object import NodeObject, Triple +from tests.test_loaders_dumpers.models.personinfo import Container, Person logger = logging.getLogger(__name__) -SCHEMA = os.path.join(INPUT_DIR, 'personinfo.yaml') -DATA = os.path.join(INPUT_DIR, 'example_personinfo_data.yaml') -OUT_TTL = os.path.join(OUTPUT_DIR, 'example_out.ttl') -OUT_JSON = os.path.join(OUTPUT_DIR, 'example_out.json') -OUT_YAML = os.path.join(OUTPUT_DIR, 'example_out.yaml') +SCHEMA = os.path.join(INPUT_DIR, "personinfo.yaml") +DATA = os.path.join(INPUT_DIR, "example_personinfo_data.yaml") +OUT_TTL = os.path.join(OUTPUT_DIR, "example_out.ttl") +OUT_JSON = os.path.join(OUTPUT_DIR, "example_out.json") +OUT_YAML = os.path.join(OUTPUT_DIR, "example_out.yaml") prefix_map = { - 'CODE': 'http://example.org/code/', - 'ROR': 'http://example.org/ror/', - 'P': 'http://example.org/P/', - 'GEO': 'http://example.org/GEO/', + "CODE": "http://example.org/code/", + "ROR": "http://example.org/ror/", + "P": "http://example.org/P/", + "GEO": "http://example.org/GEO/", } -P = Namespace('http://example.org/P/') -ROR = Namespace('http://example.org/ror/') -CODE = Namespace('http://example.org/code/') -INFO = Namespace('https://w3id.org/linkml/examples/personinfo/') -SDO = Namespace('http://schema.org/') -GSSO = Namespace('http://purl.obolibrary.org/obo/GSSO_') -HP = Namespace('http://purl.obolibrary.org/obo/HP_') -SYMP = Namespace('http://purl.obolibrary.org/obo/SYMP_') -WD = Namespace('http://www.wikidata.org/entity/') +P = Namespace("http://example.org/P/") +ROR = Namespace("http://example.org/ror/") +CODE = Namespace("http://example.org/code/") +INFO = Namespace("https://w3id.org/linkml/examples/personinfo/") +SDO = Namespace("http://schema.org/") +GSSO = Namespace("http://purl.obolibrary.org/obo/GSSO_") +HP = Namespace("http://purl.obolibrary.org/obo/HP_") +SYMP = Namespace("http://purl.obolibrary.org/obo/SYMP_") +WD = Namespace("http://www.wikidata.org/entity/") + class LoadersDumpersTestCase(unittest.TestCase): @@ -69,23 +67,23 @@ def test_load_from_list(self): Tests the load_any loader method, which can be used to load directly to a list """ view = SchemaView(SCHEMA) - with open(DATA, encoding='UTF-8') as stream: + with open(DATA, encoding="UTF-8") as stream: data = yaml.safe_load(stream) - #persons = yaml_loader.load_source(data, target_class=Person) - #container = Container(persons=persons) - person_dicts = data['persons'] + # persons = yaml_loader.load_source(data, target_class=Person) + # container = Container(persons=persons) + person_dicts = data["persons"] tuples = [(yaml_loader, yaml.dump(person_dicts)), (json_loader, json.dumps(person_dicts, default=str))] for loader, person_list_str in tuples: persons = loader.loads_any(person_list_str, target_class=Person) assert isinstance(persons, list) assert isinstance(persons[0], Person) - [p1] = [p for p in persons if p.id == 'P:001'] - [p2] = [p for p in persons if p.id == 'P:002'] - self.assertEqual(p1.name, 'fred bloggs') - self.assertEqual(p2.name, 'joe schmö') + [p1] = [p for p in persons if p.id == "P:001"] + [p2] = [p for p in persons if p.id == "P:002"] + self.assertEqual(p1.name, "fred bloggs") + self.assertEqual(p2.name, "joe schmö") self.assertEqual(p1.age_in_years, 33) - self.assertEqual(p1.gender.code.text, 'cisgender man') - self.assertEqual(p2.gender.code.text, 'transgender man') + self.assertEqual(p1.gender.code.text, "cisgender man") + self.assertEqual(p2.gender.code.text, "transgender man") def test_encoding(self): """ @@ -94,47 +92,46 @@ def test_encoding(self): # pyyaml or json read non-ascii strings just fine no matter if the # file is ascii or utf-8 encoded. So we use Python's open function # to detect undesired ascii encoding. (linkml issue #634) - with open(OUT_YAML, encoding='UTF-8') as f: - [p2_name_line] = [l for l in f.readlines() if 'joe schm' in l] - self.assertIn('joe schmö', p2_name_line) - - with open(OUT_JSON, encoding='UTF-8') as f: - [p2_name_line] = [l for l in f.readlines() if 'joe schm' in l] - self.assertIn('joe schmö', p2_name_line) + with open(OUT_YAML, encoding="UTF-8") as f: + [p2_name_line] = [l for l in f.readlines() if "joe schm" in l] + self.assertIn("joe schmö", p2_name_line) + with open(OUT_JSON, encoding="UTF-8") as f: + [p2_name_line] = [l for l in f.readlines() if "joe schm" in l] + self.assertIn("joe schmö", p2_name_line) def _check_objs(self, view: SchemaView, container: Container): persons = container.persons orgs = container.organizations.values() - [p1] = [p for p in persons if p.id == 'P:001'] - [p2] = [p for p in persons if p.id == 'P:002'] - [o1] = [o for o in orgs if o.id == 'ROR:1'] - [o2] = [o for o in orgs if o.id == 'ROR:2'] - [o3] = [o for o in orgs if o.id == 'ROR:3'] - [o4] = [o for o in orgs if o.id == 'ROR:4'] + [p1] = [p for p in persons if p.id == "P:001"] + [p2] = [p for p in persons if p.id == "P:002"] + [o1] = [o for o in orgs if o.id == "ROR:1"] + [o2] = [o for o in orgs if o.id == "ROR:2"] + [o3] = [o for o in orgs if o.id == "ROR:3"] + [o4] = [o for o in orgs if o.id == "ROR:4"] o1cats = [c.code.text for c in o1.categories] o2cats = [c.code.text for c in o2.categories] - self.assertEqual(p1.name, 'fred bloggs') - self.assertEqual(p2.name, 'joe schmö') + self.assertEqual(p1.name, "fred bloggs") + self.assertEqual(p2.name, "joe schmö") self.assertEqual(p1.age_in_years, 33) - self.assertEqual(p1.gender.code.text, 'cisgender man') - self.assertEqual(p2.gender.code.text, 'transgender man') - self.assertCountEqual(o1cats, ['non profit', 'charity']) - self.assertCountEqual(o2cats, ['shell company']) + self.assertEqual(p1.gender.code.text, "cisgender man") + self.assertEqual(p2.gender.code.text, "transgender man") + self.assertCountEqual(o1cats, ["non profit", "charity"]) + self.assertCountEqual(o2cats, ["shell company"]) p2: Person emp = p2.has_employment_history[0] - self.assertEqual(emp.started_at_time, '2019-01-01') + self.assertEqual(emp.started_at_time, "2019-01-01") self.assertEqual(emp.is_current, True) self.assertEqual(emp.employed_at, o1.id) frel = p2.has_familial_relationships[0] self.assertEqual(frel.related_to, p1.id) # TODO: check PV vs PVText - self.assertEqual(str(frel.type), 'SIBLING_OF') + self.assertEqual(str(frel.type), "SIBLING_OF") med = p2.has_medical_history[0] - self.assertEqual(med.in_location, 'GEO:1234') - self.assertEqual(med.diagnosis.id, 'CODE:D0001') - self.assertEqual(med.diagnosis.name, 'headache') - self.assertEqual(med.diagnosis.code_system, 'CODE:D') + self.assertEqual(med.in_location, "GEO:1234") + self.assertEqual(med.diagnosis.id, "CODE:D0001") + self.assertEqual(med.diagnosis.name, "headache") + self.assertEqual(med.diagnosis.code_system, "CODE:D") # Check decimal representation self.assertEqual(o1.score, Decimal(1)) self.assertEqual(o2.score, Decimal("1.5")) @@ -142,7 +139,6 @@ def _check_objs(self, view: SchemaView, container: Container): self.assertEqual(o4.score, Decimal(1)) self.assertEqual(o1.min_salary, Decimal("99999.00")) - def test_edge_cases(self): """ Tests various edge cases: @@ -154,56 +150,68 @@ def test_edge_cases(self): # schema with following characterics: # - reified triples # - object has a complex union range (experimental new feature) - view = SchemaView(os.path.join(INPUT_DIR, 'complex_range_example.yaml')) + view = SchemaView(os.path.join(INPUT_DIR, "complex_range_example.yaml")) graph = Graph() taxon_prefix_map = { - 'NCBITaxon': 'http://purl.obolibrary.org/obo/NCBITaxon_', - 'RO': 'http://purl.obolibrary.org/obo/RO_', + "NCBITaxon": "http://purl.obolibrary.org/obo/NCBITaxon_", + "RO": "http://purl.obolibrary.org/obo/RO_", } # this graph has the following characteristics # - blank nodes to represent statements # - some triples not reachable from roots # - implicit schema with complex ranges (rdf:object has range of either node or literal) - graph.parse(os.path.join(INPUT_DIR, 'bacteria-taxon-class.ttl'), format='ttl') - objs = rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=False, ## strict - allow_unprocessed_triples=True, ## known issue - prefix_map=taxon_prefix_map) + graph.parse(os.path.join(INPUT_DIR, "bacteria-taxon-class.ttl"), format="ttl") + objs = rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=False, ## strict + allow_unprocessed_triples=True, ## known issue + prefix_map=taxon_prefix_map, + ) [obj] = objs for x in obj.statements: assert x.subject is None assert x.predicate is not None assert x.object is not None - logger.info(f' x={x}') + logger.info(f" x={x}") # ranges that are objects are contracted - assert Triple(subject=None, predicate='rdfs:subClassOf', object='owl:Thing') in obj.statements - assert Triple(subject=None, predicate='rdfs:subClassOf', object='NCBITaxon:1') in obj.statements + assert Triple(subject=None, predicate="rdfs:subClassOf", object="owl:Thing") in obj.statements + assert Triple(subject=None, predicate="rdfs:subClassOf", object="NCBITaxon:1") in obj.statements # string ranges - assert Triple(subject=None, predicate='rdfs:label', object='Bacteria') in obj.statements + assert Triple(subject=None, predicate="rdfs:label", object="Bacteria") in obj.statements with self.assertRaises(ValueError) as context: - rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=False, - allow_unprocessed_triples=False, - prefix_map=taxon_prefix_map) - logger.error(f'Passed unexpectedly: there are known to be unreachable triples') + rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=False, + allow_unprocessed_triples=False, + prefix_map=taxon_prefix_map, + ) + logger.error("Passed unexpectedly: there are known to be unreachable triples") # removing complex range, object has a range of string - view.schema.slots['object'].exactly_one_of = [] + view.schema.slots["object"].exactly_one_of = [] view.set_modified() - rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=True, ## required to pass - allow_unprocessed_triples=True, - prefix_map=taxon_prefix_map) + rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=True, ## required to pass + allow_unprocessed_triples=True, + prefix_map=taxon_prefix_map, + ) with self.assertRaises(ValueError) as context: - rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=False, - allow_unprocessed_triples=True, - prefix_map=taxon_prefix_map) - logger.error(f'Passed unexpectedly: rdf:object is known to have a mix of literals and nodes') - - -if __name__ == '__main__': + rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=False, + allow_unprocessed_triples=True, + prefix_map=taxon_prefix_map, + ) + logger.error("Passed unexpectedly: rdf:object is known to have a mix of literals and nodes") + + +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_loaders_pydantic.py b/tests/test_loaders_dumpers/test_loaders_pydantic.py index 0c9c1f1d..fda5fd9e 100644 --- a/tests/test_loaders_dumpers/test_loaders_pydantic.py +++ b/tests/test_loaders_dumpers/test_loaders_pydantic.py @@ -1,6 +1,6 @@ import unittest -from linkml_runtime.loaders import yaml_loader, json_loader +from linkml_runtime.loaders import json_loader, yaml_loader from tests.test_loaders_dumpers.environment import env from tests.test_loaders_dumpers.loaderdumpertestcase import LoaderDumperTestCase from tests.test_loaders_dumpers.models.books_normalized_pydantic import BookSeries @@ -11,18 +11,19 @@ class PydanticLoadersUnitTest(LoaderDumperTestCase): env = env def test_yaml_loader_single(self): - """ Load obo_sample.yaml, emit obo_sample_yaml.yaml and compare to obo_sample_output.yaml """ - self.loader_test('book_series_lotr.yaml', BookSeries, yaml_loader) + """Load obo_sample.yaml, emit obo_sample_yaml.yaml and compare to obo_sample_output.yaml""" + self.loader_test("book_series_lotr.yaml", BookSeries, yaml_loader) def test_json_loader(self): - """ Load obo_sample.json, emit obo_sample_json.yaml and check the results """ - self.loader_test('book_series_lotr.json', BookSeries, json_loader) + """Load obo_sample.json, emit obo_sample_json.yaml and check the results""" + self.loader_test("book_series_lotr.json", BookSeries, json_loader) def test_yaml_loader_kitchen_sink(self): - self.loader_test('kitchen_sink_normalized_inst_01.yaml', Dataset, yaml_loader) + self.loader_test("kitchen_sink_normalized_inst_01.yaml", Dataset, yaml_loader) def test_json_loader_kitchen_sink(self): - self.loader_test('kitchen_sink_normalized_inst_01.json', Dataset, json_loader) + self.loader_test("kitchen_sink_normalized_inst_01.json", Dataset, json_loader) -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() diff --git a/tests/test_loaders_dumpers/test_rdflib_dumper.py b/tests/test_loaders_dumpers/test_rdflib_dumper.py index 67a68f85..542c6607 100644 --- a/tests/test_loaders_dumpers/test_rdflib_dumper.py +++ b/tests/test_loaders_dumpers/test_rdflib_dumper.py @@ -1,40 +1,43 @@ +import logging import os import unittest -import logging from pathlib import Path from curies import Converter -from rdflib import Graph, Literal, URIRef +from rdflib import Graph, Literal, Namespace, URIRef from rdflib.namespace import RDF, SKOS, XSD -from rdflib import Namespace -from linkml_runtime import MappingError, DataNotFoundError +from linkml_runtime import DataNotFoundError, MappingError from linkml_runtime.dumpers import rdflib_dumper, yaml_dumper from linkml_runtime.linkml_model import Prefix -from linkml_runtime.loaders import yaml_loader -from linkml_runtime.loaders import rdflib_loader +from linkml_runtime.loaders import rdflib_loader, yaml_loader from linkml_runtime.utils.schemaview import SchemaView from tests.test_loaders_dumpers import INPUT_DIR, OUTPUT_DIR -from tests.test_loaders_dumpers.models.personinfo import Container, Person, Address, Organization, OrganizationType from tests.test_loaders_dumpers.models.node_object import NodeObject, Triple -from tests.test_loaders_dumpers.models.phenopackets import PhenotypicFeature, OntologyClass, Phenopacket, MetaData, \ - Resource +from tests.test_loaders_dumpers.models.personinfo import Address, Container, Organization, OrganizationType, Person +from tests.test_loaders_dumpers.models.phenopackets import ( + MetaData, + OntologyClass, + Phenopacket, + PhenotypicFeature, + Resource, +) logger = logging.getLogger(__name__) -SCHEMA = os.path.join(INPUT_DIR, 'personinfo.yaml') -DATA = os.path.join(INPUT_DIR, 'example_personinfo_data.yaml') -DATA_TTL = os.path.join(INPUT_DIR, 'example_personinfo_data.ttl') -OUT = os.path.join(OUTPUT_DIR, 'example_personinfo_data.ttl') -DATA_ROUNDTRIP = os.path.join(OUTPUT_DIR, 'example_personinfo_data.roundtrip-rdf.yaml') -UNMAPPED_ROUNDTRIP = os.path.join(OUTPUT_DIR, 'example_personinfo_data.unmapped-preds.yaml') +SCHEMA = os.path.join(INPUT_DIR, "personinfo.yaml") +DATA = os.path.join(INPUT_DIR, "example_personinfo_data.yaml") +DATA_TTL = os.path.join(INPUT_DIR, "example_personinfo_data.ttl") +OUT = os.path.join(OUTPUT_DIR, "example_personinfo_data.ttl") +DATA_ROUNDTRIP = os.path.join(OUTPUT_DIR, "example_personinfo_data.roundtrip-rdf.yaml") +UNMAPPED_ROUNDTRIP = os.path.join(OUTPUT_DIR, "example_personinfo_data.unmapped-preds.yaml") PREFIX_MAP = { - 'CODE': 'http://example.org/code/', - 'ROR': 'http://example.org/ror/', - 'P': 'http://example.org/P/', - 'GEO': 'http://example.org/GEO/', + "CODE": "http://example.org/code/", + "ROR": "http://example.org/ror/", + "P": "http://example.org/P/", + "GEO": "http://example.org/GEO/", } unmapped_predicates_test_ttl = """ @@ -98,15 +101,16 @@ personinfo:street "1 foo street" ] . """ -P = Namespace('http://example.org/P/') -ROR = Namespace('http://example.org/ror/') -CODE = Namespace('http://example.org/code/') -INFO = Namespace('https://w3id.org/linkml/examples/personinfo/') -SDO = Namespace('http://schema.org/') -GSSO = Namespace('http://purl.obolibrary.org/obo/GSSO_') -HP = Namespace('http://purl.obolibrary.org/obo/HP_') -SYMP = Namespace('http://purl.obolibrary.org/obo/SYMP_') -WD = Namespace('http://www.wikidata.org/entity/') +P = Namespace("http://example.org/P/") +ROR = Namespace("http://example.org/ror/") +CODE = Namespace("http://example.org/code/") +INFO = Namespace("https://w3id.org/linkml/examples/personinfo/") +SDO = Namespace("http://schema.org/") +GSSO = Namespace("http://purl.obolibrary.org/obo/GSSO_") +HP = Namespace("http://purl.obolibrary.org/obo/HP_") +SYMP = Namespace("http://purl.obolibrary.org/obo/SYMP_") +WD = Namespace("http://www.wikidata.org/entity/") + class RdfLibDumperTestCase(unittest.TestCase): def setUp(self) -> None: @@ -118,47 +122,53 @@ def test_rdflib_dumper(self): self._check_objs(view, container) rdflib_dumper.dump(container, schemaview=view, to_file=OUT, prefix_map=self.prefix_map) g = Graph() - g.parse(OUT, format='ttl') - - self.assertIn((P['001'], RDF.type, SDO.Person), g) - self.assertIn((P['001'], SDO.name, Literal("fred bloggs")), g) - self.assertIn((P['001'], SDO.email, Literal("fred.bloggs@example.com")), g) - self.assertIn((P['001'], INFO.age_in_years, Literal(33)), g) - self.assertIn((P['001'], SDO.gender, GSSO['000371']), g) - self.assertIn((P['001'], INFO.depicted_by, Literal('https://example.org/pictures/fred.jpg', datatype=XSD.anyURI)), g) - self.assertNotIn((P['001'], INFO.depicted_by, Literal('https://example.org/pictures/fred.jpg', datatype=XSD.string)), g) - #for (s,p,o) in g.triples((None, None, None)): + g.parse(OUT, format="ttl") + + self.assertIn((P["001"], RDF.type, SDO.Person), g) + self.assertIn((P["001"], SDO.name, Literal("fred bloggs")), g) + self.assertIn((P["001"], SDO.email, Literal("fred.bloggs@example.com")), g) + self.assertIn((P["001"], INFO.age_in_years, Literal(33)), g) + self.assertIn((P["001"], SDO.gender, GSSO["000371"]), g) + self.assertIn( + (P["001"], INFO.depicted_by, Literal("https://example.org/pictures/fred.jpg", datatype=XSD.anyURI)), g + ) + self.assertNotIn( + (P["001"], INFO.depicted_by, Literal("https://example.org/pictures/fred.jpg", datatype=XSD.string)), g + ) + # for (s,p,o) in g.triples((None, None, None)): # print(f'{s} {p} {o}') - self.assertIn((CODE['D0001'], RDF.type, INFO.DiagnosisConcept), g) - self.assertIn((CODE['D0001'], RDF.type, INFO.DiagnosisConcept), g) - self.assertIn((CODE['D0001'], SKOS.exactMatch, HP['0002315']), g) - self.assertIn((CODE['D0001'], SKOS.exactMatch, WD.Q86), g) - self.assertIn((CODE['D0001'], SKOS.exactMatch, SYMP['0000504']), g) - self.assertNotIn((CODE['D0001'], SKOS.exactMatch, Literal(HP['0002315'])), g) + self.assertIn((CODE["D0001"], RDF.type, INFO.DiagnosisConcept), g) + self.assertIn((CODE["D0001"], RDF.type, INFO.DiagnosisConcept), g) + self.assertIn((CODE["D0001"], SKOS.exactMatch, HP["0002315"]), g) + self.assertIn((CODE["D0001"], SKOS.exactMatch, WD.Q86), g) + self.assertIn((CODE["D0001"], SKOS.exactMatch, SYMP["0000504"]), g) + self.assertNotIn((CODE["D0001"], SKOS.exactMatch, Literal(HP["0002315"])), g) [container] = g.subjects(RDF.type, INFO.Container) - self.assertIn((container, INFO.organizations, ROR['1']), g) - self.assertIn((container, INFO.organizations, ROR['2']), g) - self.assertIn((container, INFO.persons, P['001']), g) - self.assertIn((container, INFO.persons, P['002']), g) - container: Container = rdflib_loader.load(OUT, target_class=Container, schemaview=view, prefix_map=self.prefix_map) + self.assertIn((container, INFO.organizations, ROR["1"]), g) + self.assertIn((container, INFO.organizations, ROR["2"]), g) + self.assertIn((container, INFO.persons, P["001"]), g) + self.assertIn((container, INFO.persons, P["002"]), g) + container: Container = rdflib_loader.load( + OUT, target_class=Container, schemaview=view, prefix_map=self.prefix_map + ) self._check_objs(view, container) - #print(yaml_dumper.dumps(container)) - #person = next(p for p in container.persons if p.id == 'P:002') - #mh = person.has_medical_history[0] + # print(yaml_dumper.dumps(container)) + # person = next(p for p in container.persons if p.id == 'P:002') + # mh = person.has_medical_history[0] def test_enums(self): view = SchemaView(SCHEMA) - org1type1 = OrganizationType('non profit') ## no meaning declared - org1type2 = OrganizationType('charity') ## meaning URI is declared + org1type1 = OrganizationType("non profit") ## no meaning declared + org1type2 = OrganizationType("charity") ## meaning URI is declared assert not org1type1.meaning assert org1type2.meaning - org1 = Organization('ROR:1', categories=[org1type1, org1type2]) + org1 = Organization("ROR:1", categories=[org1type1, org1type2]) print(org1.categories) g = rdflib_dumper.as_rdf_graph(org1, schemaview=view, prefix_map=self.prefix_map) print(g) - cats = list(g.objects(ROR['1'], INFO['categories'])) + cats = list(g.objects(ROR["1"], INFO["categories"])) print(cats) - self.assertCountEqual([Literal('non profit'), URIRef('https://example.org/bizcodes/001')], cats) + self.assertCountEqual([Literal("non profit"), URIRef("https://example.org/bizcodes/001")], cats) orgs = rdflib_loader.from_rdf_graph(g, target_class=Organization, schemaview=view) assert len(orgs) == 1 [org1x] = orgs @@ -168,25 +178,27 @@ def test_enums(self): def test_undeclared_prefix_raises_error(self): view = SchemaView(SCHEMA) - org1 = Organization('foo') # not a CURIE or URI + org1 = Organization("foo") # not a CURIE or URI with self.assertRaises(Exception) as context: rdflib_dumper.as_rdf_graph(org1, schemaview=view) - org1 = Organization('http://example.org/foo/o1') + org1 = Organization("http://example.org/foo/o1") rdflib_dumper.as_rdf_graph(org1, schemaview=view) def test_base_prefix(self): view = SchemaView(SCHEMA) view.schema.prefixes["_base"] = Prefix("_base", "http://example.org/") - org1 = Organization('foo') # not a CURIE or URI + org1 = Organization("foo") # not a CURIE or URI g = rdflib_dumper.as_rdf_graph(org1, schemaview=view) - assert (URIRef('http://example.org/foo'), RDF.type, SDO.Organization) in g + assert (URIRef("http://example.org/foo"), RDF.type, SDO.Organization) in g def test_rdflib_loader(self): """ tests loading from an RDF graph """ view = SchemaView(SCHEMA) - container: Container = rdflib_loader.load(DATA_TTL, target_class=Container, schemaview=view, prefix_map=self.prefix_map) + container: Container = rdflib_loader.load( + DATA_TTL, target_class=Container, schemaview=view, prefix_map=self.prefix_map + ) self._check_objs(view, container) yaml_dumper.dump(container, to_file=DATA_ROUNDTRIP) @@ -198,27 +210,32 @@ def test_unmapped_predicates(self): view = SchemaView(SCHEMA) # default behavior is to raise error on unmapped predicates with self.assertRaises(MappingError) as context: - rdflib_loader.loads(unmapped_predicates_test_ttl, target_class=Person, - schemaview=view, prefix_map=self.prefix_map) + rdflib_loader.loads( + unmapped_predicates_test_ttl, target_class=Person, schemaview=view, prefix_map=self.prefix_map + ) # called can explicitly allow unmapped predicates to be dropped - person: Person = rdflib_loader.loads(unmapped_predicates_test_ttl, target_class=Person, - schemaview=view, prefix_map=self.prefix_map, - ignore_unmapped_predicates=True) - self.assertEqual(person.id, 'P:001') + person: Person = rdflib_loader.loads( + unmapped_predicates_test_ttl, + target_class=Person, + schemaview=view, + prefix_map=self.prefix_map, + ignore_unmapped_predicates=True, + ) + self.assertEqual(person.id, "P:001") self.assertEqual(person.age_in_years, 33) self.assertEqual(str(person.gender), "cisgender man") yaml_dumper.dump(person, to_file=UNMAPPED_ROUNDTRIP) - def test_any_of_enum(self): """ Tests https://github.com/linkml/linkml/issues/1023 """ view = SchemaView(SCHEMA) # default behavior is to raise error on unmapped predicates - person = rdflib_loader.loads(enum_union_type_test_ttl, target_class=Person, - schemaview=view, prefix_map=self.prefix_map) - self.assertEqual(person.id, 'P:001') + person = rdflib_loader.loads( + enum_union_type_test_ttl, target_class=Person, schemaview=view, prefix_map=self.prefix_map + ) + self.assertEqual(person.id, "P:001") self.assertEqual(person.age_in_years, 33) yaml_dumper.dump(person, to_file=UNMAPPED_ROUNDTRIP) cases = [ @@ -237,12 +254,12 @@ def test_unmapped_type(self): view = SchemaView(SCHEMA) # default behavior is to raise error on unmapped predicates with self.assertRaises(DataNotFoundError) as context: - rdflib_loader.loads(unmapped_type_test_ttl, target_class=Person, - schemaview=view, prefix_map=self.prefix_map) + rdflib_loader.loads( + unmapped_type_test_ttl, target_class=Person, schemaview=view, prefix_map=self.prefix_map + ) graph = Graph() - graph.parse(data=unmapped_type_test_ttl, format='ttl') - objs = rdflib_loader.from_rdf_graph(graph, target_class=Person, - schemaview=view, prefix_map=self.prefix_map) + graph.parse(data=unmapped_type_test_ttl, format="ttl") + objs = rdflib_loader.from_rdf_graph(graph, target_class=Person, schemaview=view, prefix_map=self.prefix_map) self.assertEqual(len(objs), 0) def test_blank_node(self): @@ -250,16 +267,20 @@ def test_blank_node(self): blank nodes should be retrievable """ view = SchemaView(SCHEMA) - address: Address = rdflib_loader.loads(blank_node_test_ttl, target_class=Address, - schemaview=view, prefix_map=self.prefix_map, - ignore_unmapped_predicates=True) - self.assertEqual(address.city, 'foo city') + address: Address = rdflib_loader.loads( + blank_node_test_ttl, + target_class=Address, + schemaview=view, + prefix_map=self.prefix_map, + ignore_unmapped_predicates=True, + ) + self.assertEqual(address.city, "foo city") ttl = rdflib_dumper.dumps(address, schemaview=view) print(ttl) g = Graph() - g.parse(data=ttl, format='ttl') - INFO = Namespace('https://w3id.org/linkml/examples/personinfo/') - SDO = Namespace('http://schema.org/') + g.parse(data=ttl, format="ttl") + INFO = Namespace("https://w3id.org/linkml/examples/personinfo/") + SDO = Namespace("http://schema.org/") [bn] = g.subjects(RDF.type, SDO.PostalAddress) self.assertIn((bn, RDF.type, SDO.PostalAddress), g) self.assertIn((bn, INFO.city, Literal("foo city")), g) @@ -268,33 +289,33 @@ def test_blank_node(self): def _check_objs(self, view: SchemaView, container: Container): persons = container.persons orgs = container.organizations.values() - [p1] = [p for p in persons if p.id == 'P:001'] - [p2] = [p for p in persons if p.id == 'P:002'] - [o1] = [o for o in orgs if o.id == 'ROR:1'] - [o2] = [o for o in orgs if o.id == 'ROR:2'] + [p1] = [p for p in persons if p.id == "P:001"] + [p2] = [p for p in persons if p.id == "P:002"] + [o1] = [o for o in orgs if o.id == "ROR:1"] + [o2] = [o for o in orgs if o.id == "ROR:2"] o1cats = [c.code.text for c in o1.categories] o2cats = [c.code.text for c in o2.categories] - self.assertEqual(p1.name, 'fred bloggs') - self.assertEqual(p2.name, 'joe schmö') + self.assertEqual(p1.name, "fred bloggs") + self.assertEqual(p2.name, "joe schmö") self.assertEqual(p1.age_in_years, 33) - self.assertEqual(p1.gender.code.text, 'cisgender man') - self.assertEqual(p2.gender.code.text, 'transgender man') - self.assertCountEqual(o1cats, ['non profit', 'charity']) - self.assertCountEqual(o2cats, ['shell company']) + self.assertEqual(p1.gender.code.text, "cisgender man") + self.assertEqual(p2.gender.code.text, "transgender man") + self.assertCountEqual(o1cats, ["non profit", "charity"]) + self.assertCountEqual(o2cats, ["shell company"]) p2: Person emp = p2.has_employment_history[0] - self.assertEqual(emp.started_at_time, '2019-01-01') + self.assertEqual(emp.started_at_time, "2019-01-01") self.assertEqual(emp.is_current, True) self.assertEqual(emp.employed_at, o1.id) frel = p2.has_familial_relationships[0] self.assertEqual(frel.related_to, p1.id) # TODO: check PV vs PVText - self.assertEqual(str(frel.type), 'SIBLING_OF') + self.assertEqual(str(frel.type), "SIBLING_OF") med = p2.has_medical_history[0] - self.assertEqual(med.in_location, 'GEO:1234') - self.assertEqual(med.diagnosis.id, 'CODE:D0001') - self.assertEqual(med.diagnosis.name, 'headache') - self.assertEqual(med.diagnosis.code_system, 'CODE:D') + self.assertEqual(med.in_location, "GEO:1234") + self.assertEqual(med.diagnosis.id, "CODE:D0001") + self.assertEqual(med.diagnosis.name, "headache") + self.assertEqual(med.diagnosis.code_system, "CODE:D") def test_edge_cases(self): """ @@ -307,92 +328,113 @@ def test_edge_cases(self): # schema with following characterics: # - reified triples # - object has a complex union range (experimental new feature) - view = SchemaView(os.path.join(INPUT_DIR, 'complex_range_example.yaml')) + view = SchemaView(os.path.join(INPUT_DIR, "complex_range_example.yaml")) graph = Graph() taxon_prefix_map = { - 'NCBITaxon': 'http://purl.obolibrary.org/obo/NCBITaxon_', - 'RO': 'http://purl.obolibrary.org/obo/RO_', + "NCBITaxon": "http://purl.obolibrary.org/obo/NCBITaxon_", + "RO": "http://purl.obolibrary.org/obo/RO_", } # this graph has the following characteristics # - blank nodes to represent statements # - some triples not reachable from roots # - implicit schema with complex ranges (rdf:object has range of either node or literal) - graph.parse(os.path.join(INPUT_DIR, 'bacteria-taxon-class.ttl'), format='ttl') - objs = rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=False, ## strict - allow_unprocessed_triples=True, ## known issue - prefix_map=taxon_prefix_map) + graph.parse(os.path.join(INPUT_DIR, "bacteria-taxon-class.ttl"), format="ttl") + objs = rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=False, ## strict + allow_unprocessed_triples=True, ## known issue + prefix_map=taxon_prefix_map, + ) [obj] = objs for x in obj.statements: assert x.subject is None assert x.predicate is not None assert x.object is not None - logger.info(f' x={x}') + logger.info(f" x={x}") # ranges that are objects are contracted - assert Triple(subject=None, predicate='rdfs:subClassOf', object='owl:Thing') in obj.statements - assert Triple(subject=None, predicate='rdfs:subClassOf', object='NCBITaxon:1') in obj.statements + assert Triple(subject=None, predicate="rdfs:subClassOf", object="owl:Thing") in obj.statements + assert Triple(subject=None, predicate="rdfs:subClassOf", object="NCBITaxon:1") in obj.statements # string ranges - assert Triple(subject=None, predicate='rdfs:label', object='Bacteria') in obj.statements + assert Triple(subject=None, predicate="rdfs:label", object="Bacteria") in obj.statements with self.assertRaises(ValueError) as context: - rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=False, - allow_unprocessed_triples=False, - prefix_map=taxon_prefix_map) - logger.error(f'Passed unexpectedly: there are known to be unreachable triples') + rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=False, + allow_unprocessed_triples=False, + prefix_map=taxon_prefix_map, + ) + logger.error("Passed unexpectedly: there are known to be unreachable triples") # removing complex range, object has a range of string - view.schema.slots['object'].exactly_one_of = [] + view.schema.slots["object"].exactly_one_of = [] view.set_modified() - rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=True, ## required to pass - allow_unprocessed_triples=True, - prefix_map=taxon_prefix_map) + rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=True, ## required to pass + allow_unprocessed_triples=True, + prefix_map=taxon_prefix_map, + ) with self.assertRaises(ValueError) as context: - rdflib_loader.from_rdf_graph(graph, target_class=NodeObject, - schemaview=view, - cast_literals=False, - allow_unprocessed_triples=True, - prefix_map=taxon_prefix_map) - logger.error(f'Passed unexpectedly: rdf:object is known to have a mix of literals and nodes') + rdflib_loader.from_rdf_graph( + graph, + target_class=NodeObject, + schemaview=view, + cast_literals=False, + allow_unprocessed_triples=True, + prefix_map=taxon_prefix_map, + ) + logger.error("Passed unexpectedly: rdf:object is known to have a mix of literals and nodes") def test_phenopackets(self): - view = SchemaView(str(Path(INPUT_DIR) / "phenopackets"/ "phenopackets.yaml")) - test_label = 'test label' + view = SchemaView(str(Path(INPUT_DIR) / "phenopackets" / "phenopackets.yaml")) + test_label = "test label" with self.assertRaises(ValueError) as e: - c = OntologyClass(id='NO_SUCH_PREFIX:1', label=test_label) + c = OntologyClass(id="NO_SUCH_PREFIX:1", label=test_label) rdflib_dumper.dumps(c, view) cases = [ ("HP:1", "http://purl.obolibrary.org/obo/HP_1", None), - ("FOO:1", "http://example.org/FOO_1", {'FOO': 'http://example.org/FOO_', - "@base": "http://example.org/base/"}), + ( + "FOO:1", + "http://example.org/FOO_1", + {"FOO": "http://example.org/FOO_", "@base": "http://example.org/base/"}, + ), ] for id, expected_uri, prefix_map in cases: c = OntologyClass(id=id, label=test_label) ttl = rdflib_dumper.dumps(c, view, prefix_map=prefix_map) g = Graph() - g.parse(data=ttl, format='ttl') + g.parse(data=ttl, format="ttl") self.assertEqual(len(g), 2) - self.assertIn(Literal(test_label), list(g.objects(URIRef(expected_uri))), - f'Expected label {test_label} for {expected_uri} in {ttl}') + self.assertIn( + Literal(test_label), + list(g.objects(URIRef(expected_uri))), + f"Expected label {test_label} for {expected_uri} in {ttl}", + ) pf = PhenotypicFeature(type=c) - pkt = Phenopacket(id='id with spaces', - metaData=MetaData(resources=[Resource(id='id with spaces')]), - phenotypicFeatures=[pf]) + pkt = Phenopacket( + id="id with spaces", + metaData=MetaData(resources=[Resource(id="id with spaces")]), + phenotypicFeatures=[pf], + ) ttl = rdflib_dumper.dumps(pkt, view, prefix_map=self.prefix_map) g = Graph() - g.parse(data=ttl, format='ttl') - self.assertIn(Literal(test_label), list(g.objects(URIRef(expected_uri))), - f'Expected label {test_label} for {expected_uri} in {ttl}') + g.parse(data=ttl, format="ttl") + self.assertIn( + Literal(test_label), + list(g.objects(URIRef(expected_uri))), + f"Expected label {test_label} for {expected_uri} in {ttl}", + ) if prefix_map and "@base" in prefix_map: resource_uri = URIRef(prefix_map["@base"] + "id%20with%20spaces") self.assertEqual(1, len(list(g.objects(resource_uri)))) - - class RDFLibConverterDumperTestCase(RdfLibDumperTestCase): """A test case that uses a :class:`curies.Converter` for testing loading and dumping with RDFLib.""" @@ -401,6 +443,5 @@ def setUp(self) -> None: self.prefix_map = Converter.from_prefix_map(PREFIX_MAP) - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_processing/__init__.py b/tests/test_processing/__init__.py index 5d7473b7..ff131072 100644 --- a/tests/test_processing/__init__.py +++ b/tests/test_processing/__init__.py @@ -1,7 +1,6 @@ import os - TESTING_DIR = os.path.abspath(os.path.dirname(__file__)) -INPUT_DIR = os.path.join(TESTING_DIR, 'input') -OUTPUT_DIR = os.path.join(TESTING_DIR, 'output') +INPUT_DIR = os.path.join(TESTING_DIR, "input") +OUTPUT_DIR = os.path.join(TESTING_DIR, "output") diff --git a/tests/test_processing/test_arrays.py b/tests/test_processing/test_arrays.py index d3bb6873..f4b38aff 100644 --- a/tests/test_processing/test_arrays.py +++ b/tests/test_processing/test_arrays.py @@ -3,11 +3,10 @@ import yaml -from linkml_runtime.utils.schemaview import SchemaView - from linkml_runtime.processing.referencevalidator import ( ReferenceValidator, ) +from linkml_runtime.utils.schemaview import SchemaView from tests.test_processing import INPUT_DIR @@ -18,13 +17,11 @@ class ArrayTestCase(unittest.TestCase): See: https://linkml.io/linkml/howtos/multidimensional-arrays """ - def setUp(self) -> None: sv = SchemaView(str(Path(INPUT_DIR) / "array_example.yaml")) self.normalizer = ReferenceValidator(sv) self.matrix = yaml.safe_load(open(str(Path(INPUT_DIR) / "array_example_data.yaml"))) - def test_array_normalization(self): """Test that we can infer the collection form of a slot.""" norm = self.normalizer diff --git a/tests/test_processing/test_referencevalidator.py b/tests/test_processing/test_referencevalidator.py index 6f40799d..b5468ee8 100644 --- a/tests/test_processing/test_referencevalidator.py +++ b/tests/test_processing/test_referencevalidator.py @@ -1,28 +1,27 @@ +import datetime import json import unittest -import datetime -from datetime import datetime as datetime2 from collections import namedtuple from dataclasses import dataclass, field +from datetime import datetime as datetime2 from decimal import Decimal from io import StringIO from pathlib import Path -from typing import Optional, Any, Union +from typing import Any, Optional, Union import yaml -from linkml_runtime.dumpers import yaml_dumper, json_dumper -from linkml_runtime.linkml_model import SlotDefinition, SlotDefinitionName, PermissibleValue -from linkml_runtime.utils.introspection import package_schemaview -from linkml_runtime.utils.schemaview import SchemaView - -from linkml_runtime.utils.schema_builder import SchemaBuilder +from linkml_runtime.dumpers import json_dumper, yaml_dumper +from linkml_runtime.linkml_model import PermissibleValue, SlotDefinition, SlotDefinitionName from linkml_runtime.processing.referencevalidator import ( + CollectionForm, + ConstraintType, ReferenceValidator, Report, - ConstraintType, - CollectionForm, ) +from linkml_runtime.utils.introspection import package_schemaview +from linkml_runtime.utils.schema_builder import SchemaBuilder +from linkml_runtime.utils.schemaview import SchemaView from linkml_runtime.utils.yamlutils import DupCheckYamlLoader @@ -85,9 +84,7 @@ def __repr__(self) -> str: TEST_TIME = datetime.datetime(2023, 1, 21, 17, 24, 36, 385155) -def _add_core_schema_elements( - sb: SchemaBuilder, test_slot: Optional[SlotDefinition] = None -): +def _add_core_schema_elements(sb: SchemaBuilder, test_slot: Optional[SlotDefinition] = None): sb.add_slot("id", range="string", identifier=True) sb.add_class("Identified", slots=["id", "name", "description"]) sb.add_class("NonIdentified", slots=["name", "description"]) @@ -113,21 +110,11 @@ def _serialize(obj: Any) -> str: def _normalizations(report: Report) -> str: - return ", ".join( - [ - f"{f1.value}->{f2.value}" - for f1, f2 in report.collection_form_normalizations() - ] - ) + return ", ".join([f"{f1.value}->{f2.value}" for f1, f2 in report.collection_form_normalizations()]) -def _errors(report: Report) -> str: - return ", ".join( - [ - f"{r.type}" - for r in report.errors() - ] - ) +def _errors(report: Report) -> str: + return ", ".join([f"{r.type}" for r in report.errors()]) class ReferenceValidatorTestCase(unittest.TestCase): @@ -248,9 +235,7 @@ def test_01_infer_collection_form(self): CollectionForm.CompactDict, ), ( - SlotDefinition( - "s", multivalued=True, inlined=True, range="NonIdentified" - ), + SlotDefinition("s", multivalued=True, inlined=True, range="NonIdentified"), CollectionForm.CompactDict, ), ( @@ -258,27 +243,19 @@ def test_01_infer_collection_form(self): CollectionForm.SimpleDict, ), ( - SlotDefinition( - "s", multivalued=True, inlined_as_list=True, range="Identified" - ), + SlotDefinition("s", multivalued=True, inlined_as_list=True, range="Identified"), CollectionForm.List, ), ( - SlotDefinition( - "s", multivalued=True, inlined_as_list=True, range="NonIdentified" - ), + SlotDefinition("s", multivalued=True, inlined_as_list=True, range="NonIdentified"), CollectionForm.List, ), ( - SlotDefinition( - "s", multivalued=True, inlined_as_list=True, range="Simple" - ), + SlotDefinition("s", multivalued=True, inlined_as_list=True, range="Simple"), CollectionForm.List, ), ] - doc.text( - "Expected collection form for different combinations of slot properties:" - ) + doc.text("Expected collection form for different combinations of slot properties:") doc.th(METASLOTS + ["CollectionForm"]) for slot, expected in cases: sb = SchemaBuilder() @@ -296,7 +273,6 @@ def test_01_infer_collection_form(self): expected = CollectionForm.ExpandedDict self.assertEqual(expected, inferred_form, f"expand_all={normalizer.expand_all}") - def test_02_ensure_collection_forms(self): """Test normalization into a collection form.""" doc = self.doc @@ -380,9 +356,7 @@ def test_02_ensure_collection_forms(self): ), ( CollectionForm.List, - SlotDefinition( - "s", range="NonIdentified", multivalued=True - ), # inlined is inferred + SlotDefinition("s", range="NonIdentified", multivalued=True), # inlined is inferred [ ( [obj_non_identified_minimal], @@ -417,9 +391,7 @@ def test_02_ensure_collection_forms(self): ), ( CollectionForm.List, - SlotDefinition( - "s", range="Identified", multivalued=True, inlined=False - ), + SlotDefinition("s", range="Identified", multivalued=True, inlined=False), [ (["id1"], [], [], ["id1"]), ], @@ -442,12 +414,10 @@ def test_02_ensure_collection_forms(self): {"id1": obj_identified_minimal}, ), ( - {"id1": obj_identified_minimal, - "id2": obj_identified_minimal}, + {"id1": obj_identified_minimal, "id2": obj_identified_minimal}, [], [], - {"id1": obj_identified_minimal, - "id2": obj_identified_minimal}, + {"id1": obj_identified_minimal, "id2": obj_identified_minimal}, ), ( {"id1": None}, @@ -542,23 +512,15 @@ def test_02_ensure_collection_forms(self): input, expected_repairs, expected_unrepaired, expected_output = example report = Report() if form == CollectionForm.NonCollection: - output = normalizer.ensure_non_collection( - input, slot, pk_slot_name, report - ) + output = normalizer.ensure_non_collection(input, slot, pk_slot_name, report) elif form == CollectionForm.List: output = normalizer.ensure_list(input, slot, pk_slot_name, report) elif form == CollectionForm.ExpandedDict: - output = normalizer.ensure_expanded_dict( - input, slot, pk_slot_name, report - ) + output = normalizer.ensure_expanded_dict(input, slot, pk_slot_name, report) elif form == CollectionForm.CompactDict: - output = normalizer.ensure_compact_dict( - input, slot, pk_slot_name, report - ) + output = normalizer.ensure_compact_dict(input, slot, pk_slot_name, report) elif form == CollectionForm.SimpleDict: - output = normalizer.ensure_simple_dict( - input, slot, pk_slot_name, report - ) + output = normalizer.ensure_simple_dict(input, slot, pk_slot_name, report) else: raise AssertionError(f"{form} unrecognized") doc.tr( @@ -611,12 +573,8 @@ def test_03_slot_values(self): ), [ Inst_nt("empty parent object", {}, [], [], {}), - Inst_nt( - "slot value is valid empty list", {"s": []}, [], [], {"s": []} - ), - Inst_nt( - "slot value is valid list", {"s": [ref1]}, [], [], {"s": [ref1]} - ), + Inst_nt("slot value is valid empty list", {"s": []}, [], [], {"s": []}), + Inst_nt("slot value is valid list", {"s": [ref1]}, [], [], {"s": [ref1]}), Inst_nt( "slot value is expanded dict", {"s": {ref1["id"]: ref1}}, @@ -658,9 +616,7 @@ def test_03_slot_values(self): ), [ Inst_nt("parent object is empty", {}, [], [], {}), - Inst_nt( - "slot value is valid empty list", {"s": []}, [], [], {"s": []} - ), + Inst_nt("slot value is valid empty list", {"s": []}, [], [], {"s": []}), Inst_nt( "slot value is object list", {"s": [ref1ni]}, @@ -690,9 +646,7 @@ def test_03_slot_values(self): ), [ Inst_nt("parent object is empty", {}, [], [], {}), - Inst_nt( - "slot value is empty dictionary", {"s": {}}, [], [], {"s": {}} - ), + Inst_nt("slot value is empty dictionary", {"s": {}}, [], [], {"s": {}}), Inst_nt( "slot value is inlined list", {"s": [ref1]}, @@ -886,10 +840,8 @@ def test_03_slot_values(self): len(report.normalized_results()), f"Mismatch for {slot.description} => => {inst_description} . {report.normalized_results()}", ) - self._assert_unrepaired_types_the_same( - report, expected_unrepaired, inst, output_object - ) - #doc.h4("Example") + self._assert_unrepaired_types_the_same(report, expected_unrepaired, inst, output_object) + # doc.h4("Example") if False: if report.normalized_results(): @@ -902,12 +854,15 @@ def test_03_slot_values(self): doc.text("Validation Errors (Post-Normalization)") for r in report.results_excluding_normalized(): doc.object(r) - doc.tr([inst_description, - _serialize(inst), - _serialize(output_object), - _normalizations(report), - _errors(report), - ]) + doc.tr( + [ + inst_description, + _serialize(inst), + _serialize(output_object), + _normalizations(report), + _errors(report), + ] + ) def test_05_type_ranges(self): cases = [ @@ -972,9 +927,7 @@ def test_06_object_ranges(self): cn, inst, expected_problems = case report = Report() normalizer.normalize_object(inst, derived_schema.classes[cn], report) - self._assert_unrepaired_types_the_same( - report, expected_problems, inst, inst - ) + self._assert_unrepaired_types_the_same(report, expected_problems, inst, inst) def test_07_normalize_enums(self): sb = SchemaBuilder() @@ -993,14 +946,10 @@ def test_07_normalize_enums(self): expected_output, ) in cases: report = Report() - output = normalizer.normalize_enum( - input_object, derived_schema.enums["TestEnum"], report - ) + output = normalizer.normalize_enum(input_object, derived_schema.enums["TestEnum"], report) self.assertEqual(expected_output, output) self.assertCountEqual(expected_repairs, report.normalized_results()) - self._assert_unrepaired_types_the_same( - report, expected_unrepaired, input_object, output - ) + self._assert_unrepaired_types_the_same(report, expected_unrepaired, input_object, output) def test_08_normalize_types(self): doc = self.doc @@ -1109,30 +1058,20 @@ def test_08_normalize_types(self): for v, expected_repairs, expected_unrepaired, expected_value in examples: # test with custom type report = Report() - normalized_value = normalizer.normalize_type( - v, derived_schema.types[f"my_{t}"], report - ) - self.assertEqual( - expected_value, normalized_value, f"Failed to normalize {v} to {t}" - ) + normalized_value = normalizer.normalize_type(v, derived_schema.types[f"my_{t}"], report) + self.assertEqual(expected_value, normalized_value, f"Failed to normalize {v} to {t}") self.assertEqual( len(report.normalized_results()), len(expected_repairs), f"{v} -> {expected_value} type {t}: Expected {expected_repairs} repairs, got {report.normalized_results()}", ) - self._assert_unrepaired_types_the_same( - report, expected_unrepaired, v, expected_value - ) + self._assert_unrepaired_types_the_same(report, expected_unrepaired, v, expected_value) # test with built-in type report = Report() - normalized_value = normalizer.normalize_type( - v, derived_schema.types[t], report - ) + normalized_value = normalizer.normalize_type(v, derived_schema.types[t], report) self.assertEqual(expected_value, normalized_value) self.assertEqual(len(report.normalized_results()), len(expected_repairs)) - self._assert_unrepaired_types_the_same( - report, expected_unrepaired, v, expected_value - ) + self._assert_unrepaired_types_the_same(report, expected_unrepaired, v, expected_value) def test_derived_schema_for_metadata(self): view = package_schemaview("linkml_runtime.linkml_model.meta") @@ -1169,9 +1108,7 @@ def test_examples_against_metamodel(self): sdc = derived_schema.classes["schema_definition"] prefixes_slot = sdc.attributes["prefixes"] cf = validator.infer_slot_collection_form(prefixes_slot) - simple_dict_value_slot = validator._slot_as_simple_dict_value_slot( - sdc.attributes["prefixes"] - ) + simple_dict_value_slot = validator._slot_as_simple_dict_value_slot(sdc.attributes["prefixes"]) # print(simple_dict_value_slot.name) # print(cf) self.assertEqual(CollectionForm.SimpleDict, cf) @@ -1218,4 +1155,4 @@ def test_metamodel(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/tests/test_utils/__init__.py b/tests/test_utils/__init__.py index ac98c179..17e1f7eb 100644 --- a/tests/test_utils/__init__.py +++ b/tests/test_utils/__init__.py @@ -5,5 +5,5 @@ TESTING_DIR = os.path.abspath(os.path.dirname(__file__)) -INPUT_DIR = os.path.join(TESTING_DIR, 'input') -OUTPUT_DIR = os.path.join(TESTING_DIR, 'output') +INPUT_DIR = os.path.join(TESTING_DIR, "input") +OUTPUT_DIR = os.path.join(TESTING_DIR, "output") diff --git a/tests/test_utils/input/inlined_as_dict.py b/tests/test_utils/input/inlined_as_dict.py index e4ecabe6..e0e0ff06 100644 --- a/tests/test_utils/input/inlined_as_dict.py +++ b/tests/test_utils/input/inlined_as_dict.py @@ -6,27 +6,27 @@ # description: Test schema for inlined_as_dict # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.metamodelcore import empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.metamodelcore import empty_dict +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" # Namespaces -EX = CurieNamespace('ex', 'https://example.org/inlined_as_dict#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +EX = CurieNamespace("ex", "https://example.org/inlined_as_dict#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = EX # Types class String(str): - """ A character string """ + """A character string""" + type_class_uri = XSD.string type_class_curie = "xsd:string" type_name = "string" @@ -34,7 +34,8 @@ class String(str): class Integer(int): - """ An integer """ + """An integer""" + type_class_uri = XSD.integer type_class_curie = "xsd:integer" type_name = "integer" @@ -94,4 +95,3 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): # Slots - diff --git a/tests/test_utils/input/inlined_as_list.py b/tests/test_utils/input/inlined_as_list.py index c50d2fe0..9836ccfb 100644 --- a/tests/test_utils/input/inlined_as_list.py +++ b/tests/test_utils/input/inlined_as_list.py @@ -6,27 +6,27 @@ # description: Test schema for inlined_as_dict # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.metamodelcore import empty_dict -from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.metamodelcore import empty_dict +from linkml_runtime.utils.yamlutils import YAMLRoot, extended_str metamodel_version = "1.7.0" # Namespaces -EX = CurieNamespace('ex', 'https://example.org/inlined_as_dict#') -XSD = CurieNamespace('xsd', 'http://www.w3.org/2001/XMLSchema#') +EX = CurieNamespace("ex", "https://example.org/inlined_as_dict#") +XSD = CurieNamespace("xsd", "http://www.w3.org/2001/XMLSchema#") DEFAULT_ = EX # Types class String(str): - """ A character string """ + """A character string""" + type_class_uri = XSD.string type_class_curie = "xsd:string" type_name = "string" @@ -34,7 +34,8 @@ class String(str): class Integer(int): - """ An integer """ + """An integer""" + type_class_uri = XSD.integer type_class_curie = "xsd:integer" type_name = "integer" @@ -94,4 +95,3 @@ def __post_init__(self, *_: list[str], **kwargs: dict[str, Any]): # Slots - diff --git a/tests/test_utils/model/inference_example.py b/tests/test_utils/model/inference_example.py index 76888dd9..1fc60561 100644 --- a/tests/test_utils/model/inference_example.py +++ b/tests/test_utils/model/inference_example.py @@ -6,30 +6,29 @@ # description: This demonstrates the use of inference # license: https://creativecommons.org/publicdomain/zero/1.0/ -import dataclasses -from jsonasobj2 import as_dict -from typing import Optional, Union, ClassVar, Any from dataclasses import dataclass -from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue +from typing import Any, ClassVar, Optional, Union -from linkml_runtime.utils.slot import Slot -from linkml_runtime.utils.metamodelcore import empty_list -from linkml_runtime.utils.yamlutils import YAMLRoot -from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from jsonasobj2 import as_dict from rdflib import URIRef -from linkml_runtime.utils.curienamespace import CurieNamespace + +from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue from linkml_runtime.linkml_model.types import Decimal -from linkml_runtime.utils.metamodelcore import Bool, Decimal +from linkml_runtime.utils.curienamespace import CurieNamespace +from linkml_runtime.utils.enumerations import EnumDefinitionImpl +from linkml_runtime.utils.metamodelcore import Bool, empty_list +from linkml_runtime.utils.slot import Slot +from linkml_runtime.utils.yamlutils import YAMLRoot metamodel_version = "1.7.0" # Namespaces -EX = CurieNamespace('ex', 'https://w3id.org/linkml/examples/inference/') -LINKML = CurieNamespace('linkml', 'https://w3id.org/linkml/') -PAV = CurieNamespace('pav', 'http://purl.org/pav/') -SCHEMA = CurieNamespace('schema', 'http://schema.org/') -SH = CurieNamespace('sh', 'https://w3id.org/shacl/') -SKOS = CurieNamespace('skos', 'http://www.w3.org/2004/02/skos/core#') +EX = CurieNamespace("ex", "https://w3id.org/linkml/examples/inference/") +LINKML = CurieNamespace("linkml", "https://w3id.org/linkml/") +PAV = CurieNamespace("pav", "http://purl.org/pav/") +SCHEMA = CurieNamespace("schema", "http://schema.org/") +SH = CurieNamespace("sh", "https://w3id.org/shacl/") +SKOS = CurieNamespace("skos", "http://www.w3.org/2004/02/skos/core#") DEFAULT_ = EX @@ -38,7 +37,6 @@ # Class references - @dataclass class Term(YAMLRoot): _inherited_slots: ClassVar[list[str]] = [] @@ -240,90 +238,229 @@ class AgeEnum(EnumDefinitionImpl): name="AgeEnum", ) + # Slots class slots: pass -slots.id = Slot(uri=EX.id, name="id", curie=EX.curie('id'), - model_uri=EX.id, domain=None, range=Optional[str]) - -slots.name = Slot(uri=EX.name, name="name", curie=EX.curie('name'), - model_uri=EX.name, domain=None, range=Optional[str]) - -slots.synonyms = Slot(uri=EX.synonyms, name="synonyms", curie=EX.curie('synonyms'), - model_uri=EX.synonyms, domain=None, range=Optional[Union[str, list[str]]]) - -slots.full_name = Slot(uri=EX.full_name, name="full_name", curie=EX.curie('full_name'), - model_uri=EX.full_name, domain=None, range=Optional[str]) - -slots.first_name = Slot(uri=EX.first_name, name="first_name", curie=EX.curie('first_name'), - model_uri=EX.first_name, domain=None, range=Optional[str]) - -slots.last_name = Slot(uri=EX.last_name, name="last_name", curie=EX.curie('last_name'), - model_uri=EX.last_name, domain=None, range=Optional[str]) - -slots.age_in_years = Slot(uri=EX.age_in_years, name="age_in_years", curie=EX.curie('age_in_years'), - model_uri=EX.age_in_years, domain=None, range=Optional[Decimal]) - -slots.age_in_months = Slot(uri=EX.age_in_months, name="age_in_months", curie=EX.curie('age_in_months'), - model_uri=EX.age_in_months, domain=None, range=Optional[Decimal]) - -slots.is_juvenile = Slot(uri=EX.is_juvenile, name="is_juvenile", curie=EX.curie('is_juvenile'), - model_uri=EX.is_juvenile, domain=None, range=Optional[Union[bool, Bool]]) - -slots.age_category = Slot(uri=EX.age_category, name="age_category", curie=EX.curie('age_category'), - model_uri=EX.age_category, domain=None, range=Optional[Union[str, "AgeEnum"]]) - -slots.prohibited = Slot(uri=EX.prohibited, name="prohibited", curie=EX.curie('prohibited'), - model_uri=EX.prohibited, domain=None, range=Optional[str]) - -slots.street = Slot(uri=EX.street, name="street", curie=EX.curie('street'), - model_uri=EX.street, domain=None, range=Optional[str]) - -slots.city = Slot(uri=EX.city, name="city", curie=EX.curie('city'), - model_uri=EX.city, domain=None, range=Optional[str]) - -slots.verbatim = Slot(uri=EX.verbatim, name="verbatim", curie=EX.curie('verbatim'), - model_uri=EX.verbatim, domain=None, range=Optional[str]) - -slots.primary_address = Slot(uri=EX.primary_address, name="primary_address", curie=EX.curie('primary_address'), - model_uri=EX.primary_address, domain=None, range=Optional[Union[dict, Address]]) - -slots.description = Slot(uri=EX.description, name="description", curie=EX.curie('description'), - model_uri=EX.description, domain=None, range=Optional[str]) - -slots.summary = Slot(uri=EX.summary, name="summary", curie=EX.curie('summary'), - model_uri=EX.summary, domain=None, range=Optional[str]) - -slots.slot_with_spaces = Slot(uri=EX.slot_with_spaces, name="slot with spaces", curie=EX.curie('slot_with_spaces'), - model_uri=EX.slot_with_spaces, domain=None, range=Optional[str]) - -slots.derived_slot_with_spaces = Slot(uri=EX.derived_slot_with_spaces, name="derived slot with spaces", curie=EX.curie('derived_slot_with_spaces'), - model_uri=EX.derived_slot_with_spaces, domain=None, range=Optional[str]) - -slots.derived_expression_from_spaces = Slot(uri=EX.derived_expression_from_spaces, name="derived expression from spaces", curie=EX.curie('derived_expression_from_spaces'), - model_uri=EX.derived_expression_from_spaces, domain=None, range=Optional[str]) - -slots.relationship__person1 = Slot(uri=EX.person1, name="relationship__person1", curie=EX.curie('person1'), - model_uri=EX.relationship__person1, domain=None, range=Optional[Union[dict, Person]]) - -slots.relationship__person2 = Slot(uri=EX.person2, name="relationship__person2", curie=EX.curie('person2'), - model_uri=EX.relationship__person2, domain=None, range=Optional[Union[dict, Person]]) - -slots.relationship__type = Slot(uri=EX.type, name="relationship__type", curie=EX.curie('type'), - model_uri=EX.relationship__type, domain=None, range=Optional[str]) - -slots.relationship__description = Slot(uri=EX.description, name="relationship__description", curie=EX.curie('description'), - model_uri=EX.relationship__description, domain=None, range=Optional[str]) - -slots.relationship__description2 = Slot(uri=EX.description2, name="relationship__description2", curie=EX.curie('description2'), - model_uri=EX.relationship__description2, domain=None, range=Optional[str]) - -slots.container__persons = Slot(uri=EX.persons, name="container__persons", curie=EX.curie('persons'), - model_uri=EX.container__persons, domain=None, range=Optional[Union[Union[dict, Person], list[Union[dict, Person]]]]) - -slots.Person_description = Slot(uri=EX.description, name="Person_description", curie=EX.curie('description'), - model_uri=EX.Person_description, domain=Person, range=Optional[str]) -slots.Person_summary = Slot(uri=EX.summary, name="Person_summary", curie=EX.curie('summary'), - model_uri=EX.Person_summary, domain=Person, range=Optional[str]) +slots.id = Slot(uri=EX.id, name="id", curie=EX.curie("id"), model_uri=EX.id, domain=None, range=Optional[str]) + +slots.name = Slot(uri=EX.name, name="name", curie=EX.curie("name"), model_uri=EX.name, domain=None, range=Optional[str]) + +slots.synonyms = Slot( + uri=EX.synonyms, + name="synonyms", + curie=EX.curie("synonyms"), + model_uri=EX.synonyms, + domain=None, + range=Optional[Union[str, list[str]]], +) + +slots.full_name = Slot( + uri=EX.full_name, + name="full_name", + curie=EX.curie("full_name"), + model_uri=EX.full_name, + domain=None, + range=Optional[str], +) + +slots.first_name = Slot( + uri=EX.first_name, + name="first_name", + curie=EX.curie("first_name"), + model_uri=EX.first_name, + domain=None, + range=Optional[str], +) + +slots.last_name = Slot( + uri=EX.last_name, + name="last_name", + curie=EX.curie("last_name"), + model_uri=EX.last_name, + domain=None, + range=Optional[str], +) + +slots.age_in_years = Slot( + uri=EX.age_in_years, + name="age_in_years", + curie=EX.curie("age_in_years"), + model_uri=EX.age_in_years, + domain=None, + range=Optional[Decimal], +) + +slots.age_in_months = Slot( + uri=EX.age_in_months, + name="age_in_months", + curie=EX.curie("age_in_months"), + model_uri=EX.age_in_months, + domain=None, + range=Optional[Decimal], +) + +slots.is_juvenile = Slot( + uri=EX.is_juvenile, + name="is_juvenile", + curie=EX.curie("is_juvenile"), + model_uri=EX.is_juvenile, + domain=None, + range=Optional[Union[bool, Bool]], +) + +slots.age_category = Slot( + uri=EX.age_category, + name="age_category", + curie=EX.curie("age_category"), + model_uri=EX.age_category, + domain=None, + range=Optional[Union[str, "AgeEnum"]], +) + +slots.prohibited = Slot( + uri=EX.prohibited, + name="prohibited", + curie=EX.curie("prohibited"), + model_uri=EX.prohibited, + domain=None, + range=Optional[str], +) + +slots.street = Slot( + uri=EX.street, name="street", curie=EX.curie("street"), model_uri=EX.street, domain=None, range=Optional[str] +) + +slots.city = Slot(uri=EX.city, name="city", curie=EX.curie("city"), model_uri=EX.city, domain=None, range=Optional[str]) + +slots.verbatim = Slot( + uri=EX.verbatim, + name="verbatim", + curie=EX.curie("verbatim"), + model_uri=EX.verbatim, + domain=None, + range=Optional[str], +) + +slots.primary_address = Slot( + uri=EX.primary_address, + name="primary_address", + curie=EX.curie("primary_address"), + model_uri=EX.primary_address, + domain=None, + range=Optional[Union[dict, Address]], +) + +slots.description = Slot( + uri=EX.description, + name="description", + curie=EX.curie("description"), + model_uri=EX.description, + domain=None, + range=Optional[str], +) + +slots.summary = Slot( + uri=EX.summary, name="summary", curie=EX.curie("summary"), model_uri=EX.summary, domain=None, range=Optional[str] +) + +slots.slot_with_spaces = Slot( + uri=EX.slot_with_spaces, + name="slot with spaces", + curie=EX.curie("slot_with_spaces"), + model_uri=EX.slot_with_spaces, + domain=None, + range=Optional[str], +) + +slots.derived_slot_with_spaces = Slot( + uri=EX.derived_slot_with_spaces, + name="derived slot with spaces", + curie=EX.curie("derived_slot_with_spaces"), + model_uri=EX.derived_slot_with_spaces, + domain=None, + range=Optional[str], +) + +slots.derived_expression_from_spaces = Slot( + uri=EX.derived_expression_from_spaces, + name="derived expression from spaces", + curie=EX.curie("derived_expression_from_spaces"), + model_uri=EX.derived_expression_from_spaces, + domain=None, + range=Optional[str], +) + +slots.relationship__person1 = Slot( + uri=EX.person1, + name="relationship__person1", + curie=EX.curie("person1"), + model_uri=EX.relationship__person1, + domain=None, + range=Optional[Union[dict, Person]], +) + +slots.relationship__person2 = Slot( + uri=EX.person2, + name="relationship__person2", + curie=EX.curie("person2"), + model_uri=EX.relationship__person2, + domain=None, + range=Optional[Union[dict, Person]], +) + +slots.relationship__type = Slot( + uri=EX.type, + name="relationship__type", + curie=EX.curie("type"), + model_uri=EX.relationship__type, + domain=None, + range=Optional[str], +) + +slots.relationship__description = Slot( + uri=EX.description, + name="relationship__description", + curie=EX.curie("description"), + model_uri=EX.relationship__description, + domain=None, + range=Optional[str], +) + +slots.relationship__description2 = Slot( + uri=EX.description2, + name="relationship__description2", + curie=EX.curie("description2"), + model_uri=EX.relationship__description2, + domain=None, + range=Optional[str], +) + +slots.container__persons = Slot( + uri=EX.persons, + name="container__persons", + curie=EX.curie("persons"), + model_uri=EX.container__persons, + domain=None, + range=Optional[Union[Union[dict, Person], list[Union[dict, Person]]]], +) + +slots.Person_description = Slot( + uri=EX.description, + name="Person_description", + curie=EX.curie("description"), + model_uri=EX.Person_description, + domain=Person, + range=Optional[str], +) + +slots.Person_summary = Slot( + uri=EX.summary, + name="Person_summary", + curie=EX.curie("summary"), + model_uri=EX.Person_summary, + domain=Person, + range=Optional[str], +) diff --git a/tests/test_utils/test_context_utils.py b/tests/test_utils/test_context_utils.py index 8e8bd2b8..377e20d9 100644 --- a/tests/test_utils/test_context_utils.py +++ b/tests/test_utils/test_context_utils.py @@ -3,7 +3,7 @@ from jsonasobj2 import JsonObj, loads from linkml_runtime.utils.context_utils import merge_contexts -from tests.test_utils import METAMODEL_CONTEXT_URI, META_BASE_URI +from tests.test_utils import META_BASE_URI, METAMODEL_CONTEXT_URI json_1 = '{ "ex": "http://example.org/test/", "ex2": "http://example.org/test2/" }' json_2 = '{ "foo": 17, "@context": { "ex": "http://example.org/test3/", "ex2": {"@id": "http://example.org/test4/" }}}' @@ -29,40 +29,58 @@ class ContextUtilsTestCase(unittest.TestCase): def test_merge_contexts(self): self.assertIsNone(merge_contexts()) - self.assertEqual('file://local.jsonld', merge_contexts("local.jsonld")['@context']) - self.assertEqual('file://local.jsonld', merge_contexts(["local.jsonld"])['@context']) - self.assertEqual(METAMODEL_CONTEXT_URI, merge_contexts(METAMODEL_CONTEXT_URI)['@context']) - self.assertEqual(METAMODEL_CONTEXT_URI, merge_contexts([METAMODEL_CONTEXT_URI])['@context']) - self.assertEqual(JsonObj(ex='http://example.org/test/', ex2='http://example.org/test2/'), - merge_contexts(json_1)['@context']) - self.assertEqual(JsonObj(ex='http://example.org/test/', ex2='http://example.org/test2/'), - merge_contexts([json_1])['@context']) - self.assertEqual(JsonObj(ex='http://example.org/test3/', ex2=JsonObj(**{'@id': 'http://example.org/test4/'})), - merge_contexts(json_2)['@context']) - self.assertEqual(JsonObj(ex='http://example.org/test3/', ex2=JsonObj(**{'@id': 'http://example.org/test4/'})), - merge_contexts([json_2])['@context']) - self.assertEqual([f'file://local.jsonld', - 'https://w3id.org/linkml/meta.context.jsonld', - JsonObj(ex='http://example.org/test/', ex2='http://example.org/test2/'), - JsonObj(ex='http://example.org/test3/', ex2=JsonObj(**{'@id': 'http://example.org/test4/'}))], - merge_contexts(["local.jsonld", METAMODEL_CONTEXT_URI, json_1, json_2])['@context']) - self.assertEqual(loads(context_output), - merge_contexts(["local.jsonld", METAMODEL_CONTEXT_URI, json_1, json_2])) + self.assertEqual("file://local.jsonld", merge_contexts("local.jsonld")["@context"]) + self.assertEqual("file://local.jsonld", merge_contexts(["local.jsonld"])["@context"]) + self.assertEqual(METAMODEL_CONTEXT_URI, merge_contexts(METAMODEL_CONTEXT_URI)["@context"]) + self.assertEqual(METAMODEL_CONTEXT_URI, merge_contexts([METAMODEL_CONTEXT_URI])["@context"]) + self.assertEqual( + JsonObj(ex="http://example.org/test/", ex2="http://example.org/test2/"), merge_contexts(json_1)["@context"] + ) + self.assertEqual( + JsonObj(ex="http://example.org/test/", ex2="http://example.org/test2/"), + merge_contexts([json_1])["@context"], + ) + self.assertEqual( + JsonObj(ex="http://example.org/test3/", ex2=JsonObj(**{"@id": "http://example.org/test4/"})), + merge_contexts(json_2)["@context"], + ) + self.assertEqual( + JsonObj(ex="http://example.org/test3/", ex2=JsonObj(**{"@id": "http://example.org/test4/"})), + merge_contexts([json_2])["@context"], + ) + self.assertEqual( + [ + "file://local.jsonld", + "https://w3id.org/linkml/meta.context.jsonld", + JsonObj(ex="http://example.org/test/", ex2="http://example.org/test2/"), + JsonObj(ex="http://example.org/test3/", ex2=JsonObj(**{"@id": "http://example.org/test4/"})), + ], + merge_contexts(["local.jsonld", METAMODEL_CONTEXT_URI, json_1, json_2])["@context"], + ) + self.assertEqual(loads(context_output), merge_contexts(["local.jsonld", METAMODEL_CONTEXT_URI, json_1, json_2])) # Dups are not removed self.assertEqual( - JsonObj(**{'@context': [JsonObj(ex='http://example.org/test/', ex2='http://example.org/test2/'), - JsonObj(ex='http://example.org/test/', ex2='http://example.org/test2/')]}), - merge_contexts([json_1, json_1])) - self.assertEqual('file://local.jsonld', merge_contexts("local.jsonld")['@context']) + JsonObj( + **{ + "@context": [ + JsonObj(ex="http://example.org/test/", ex2="http://example.org/test2/"), + JsonObj(ex="http://example.org/test/", ex2="http://example.org/test2/"), + ] + } + ), + merge_contexts([json_1, json_1]), + ) + self.assertEqual("file://local.jsonld", merge_contexts("local.jsonld")["@context"]) def test_merge_contexts_base(self): self.assertEqual( - JsonObj(**{'@context': - JsonObj(**{'@base': 'file://relloc'})}), - merge_contexts(base='file://relloc')) + JsonObj(**{"@context": JsonObj(**{"@base": "file://relloc"})}), merge_contexts(base="file://relloc") + ) self.assertEqual(loads(f'{{"@context": {{"@base": "{META_BASE_URI}"}}}}'), merge_contexts(base=META_BASE_URI)) - self.assertEqual(loads(""" + self.assertEqual( + loads( + """ {"@context": [ "https://w3id.org/linkml/meta.context.jsonld", { @@ -79,8 +97,11 @@ def test_merge_contexts_base(self): "@base": "https://w3id.org/linkml/" } ] -}"""), merge_contexts([METAMODEL_CONTEXT_URI, json_1, json_2], base=META_BASE_URI)) +}""" + ), + merge_contexts([METAMODEL_CONTEXT_URI, json_1, json_2], base=META_BASE_URI), + ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_curienamespace.py b/tests/test_utils/test_curienamespace.py index 3acec7ce..36e84346 100644 --- a/tests/test_utils/test_curienamespace.py +++ b/tests/test_utils/test_curienamespace.py @@ -7,17 +7,18 @@ class CurieNamespaceTestCase(unittest.TestCase): def test_basics(self): - BFO = CurieNamespace('bfo', "http://purl.obolibrary.org/obo/BFO_") + BFO = CurieNamespace("bfo", "http://purl.obolibrary.org/obo/BFO_") self.assertEqual(URIRef("http://purl.obolibrary.org/obo/BFO_test"), BFO.test) self.assertEqual("http://purl.obolibrary.org/obo/BFO_", BFO) - self.assertEqual("bfo:test", BFO.curie('test')) + self.assertEqual("bfo:test", BFO.curie("test")) self.assertEqual("bfo:", BFO.curie()) @unittest.expectedFailure def test_curie_as_curie(self): """ "curie can't be a local name at the moment" """ - BFO = CurieNamespace('bfo', "http://purl.obolibrary.org/obo/BFO_") + BFO = CurieNamespace("bfo", "http://purl.obolibrary.org/obo/BFO_") self.assertEqual("bfo:curie", BFO.curie) -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_dict_utils.py b/tests/test_utils/test_dict_utils.py index e0beedce..46dfc444 100644 --- a/tests/test_utils/test_dict_utils.py +++ b/tests/test_utils/test_dict_utils.py @@ -1,12 +1,12 @@ import unittest -from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition, ElementName - import linkml_runtime.utils.yamlutils as yutils +from linkml_runtime.linkml_model.meta import ClassDefinition, ElementName, SlotDefinition from linkml_runtime.utils.dictutils import as_simple_dict from tests.support.test_environment import TestEnvironmentTestCase from tests.test_utils.environment import env + def _signature(d): if isinstance(d, dict): for x in d.values(): @@ -17,10 +17,12 @@ def _signature(d): else: yield d + def _is_python_type(obj): t = type(obj) return t in [dict, list, str, int, float, type(None)] or isinstance(obj, ElementName) + def _is_basic_type(obj): return _is_python_type(obj) or isinstance(obj, ElementName) @@ -29,24 +31,24 @@ class DictUtilTestCase(TestEnvironmentTestCase): env = env def test_as_dict(self): - obj = ClassDefinition('test class') - obj2 = ClassDefinition('test class', slot_usage={'foo': SlotDefinition(name='foo', range='bar')}) - #obj2.slot_usage = {'foo': SlotDefinition(name='foo', range='bar')} + obj = ClassDefinition("test class") + obj2 = ClassDefinition("test class", slot_usage={"foo": SlotDefinition(name="foo", range="bar")}) + # obj2.slot_usage = {'foo': SlotDefinition(name='foo', range='bar')} # as dict preserves nones and empty lists d = yutils.as_dict(obj) assert isinstance(d, dict) - assert d['name'] == 'test class' - assert d['id_prefixes'] == [] - assert d['description'] is None + assert d["name"] == "test class" + assert d["id_prefixes"] == [] + assert d["description"] is None for x in _signature(d): if not _is_python_type(x): - print(f' ****={x} {type(x)}') + print(f" ****={x} {type(x)}") assert all(_is_basic_type(x) for x in _signature(d)) d2 = yutils.as_dict(obj2) print(d2) - assert d2['slot_usage']['foo']['range'] == 'bar' + assert d2["slot_usage"]["foo"]["range"] == "bar" assert all(_is_basic_type(x) for x in _signature(d2)) # as_simple_dict removes nones and empty lists @@ -54,24 +56,21 @@ def test_as_dict(self): print(d) assert isinstance(d, dict) assert all(_is_python_type(x) for x in _signature(d)) - assert d == {'name': 'test class'} + assert d == {"name": "test class"} d2 = as_simple_dict(obj2) print(d2) assert isinstance(d2, dict) - assert d2 == {'name': 'test class', 'slot_usage': {'foo': {'name': 'foo', 'range': 'bar'}}} + assert d2 == {"name": "test class", "slot_usage": {"foo": {"name": "foo", "range": "bar"}}} s = yutils.as_yaml(obj) print(s) - assert(s.strip() == 'name: test class') + assert s.strip() == "name: test class" s2 = yutils.as_yaml(obj2) print(s2) - assert(s2.strip().startswith('name: test class')) - - - + assert s2.strip().startswith("name: test class") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_distroutils.py b/tests/test_utils/test_distroutils.py index c7235dbb..ebd587a6 100644 --- a/tests/test_utils/test_distroutils.py +++ b/tests/test_utils/test_distroutils.py @@ -6,12 +6,12 @@ class DistroUtilsTestCase(unittest.TestCase): def test_distroutils(self): - p = 'linkml_runtime.linkml_model.meta' + p = "linkml_runtime.linkml_model.meta" js = get_jsonschema_string(p) - assert 'ClassDefinition' in js + assert "ClassDefinition" in js ys = get_schema_string(p) - assert 'class_definition' in ys + assert "class_definition" in ys -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_eval_utils.py b/tests/test_utils/test_eval_utils.py index dc2bd92f..8c153d6e 100644 --- a/tests/test_utils/test_eval_utils.py +++ b/tests/test_utils/test_eval_utils.py @@ -28,11 +28,11 @@ def test_eval_expressions(): assert eval_expr("1 + 2") == 3 assert eval_expr("1 + 2 + 3") == 6 assert eval_expr("{z} + 2", z=1) == 3 - assert eval_expr('{x} + {y}', x=5, y=None) is None - assert eval_expr("'x' + 'y'") == 'xy' - assert eval_expr("['a','b'] + ['c','d']") == ['a', 'b', 'c', 'd'] - assert eval_expr("{x} + {y}", x=['a', 'b'], y=['c', 'd']) == ['a', 'b', 'c', 'd'] - assert eval_expr("{'a': 1}") == {'a': 1} + assert eval_expr("{x} + {y}", x=5, y=None) is None + assert eval_expr("'x' + 'y'") == "xy" + assert eval_expr("['a','b'] + ['c','d']") == ["a", "b", "c", "d"] + assert eval_expr("{x} + {y}", x=["a", "b"], y=["c", "d"]) == ["a", "b", "c", "d"] + assert eval_expr("{'a': 1}") == {"a": 1} assert eval_expr("max([1, 5, 2])") == 5 assert eval_expr("max({x})", x=[1, 5, 2]) == 5 assert eval_expr("True") is True @@ -42,35 +42,35 @@ def test_eval_expressions(): assert eval_expr("1 <= 1") is True assert eval_expr("1 >= 1") is True assert eval_expr("2 > 1") is True - assert eval_expr("'EQ' if {x} == {y} else 'NEQ'", x=1, y=1) == 'EQ' - assert eval_expr("'EQ' if {x} == {y} else 'NEQ'", x=1, y=2) == 'NEQ' - assert eval_expr("'NOT_NULL' if x else 'NULL'", x=1) == 'NOT_NULL' - assert eval_expr("'NOT_NULL' if x else 'NULL'", x=None) == 'NULL' - assert eval_expr("'EQ' if {x} == {y} else 'NEQ'", x=1, y=2) == 'NEQ' + assert eval_expr("'EQ' if {x} == {y} else 'NEQ'", x=1, y=1) == "EQ" + assert eval_expr("'EQ' if {x} == {y} else 'NEQ'", x=1, y=2) == "NEQ" + assert eval_expr("'NOT_NULL' if x else 'NULL'", x=1) == "NOT_NULL" + assert eval_expr("'NOT_NULL' if x else 'NULL'", x=None) == "NULL" + assert eval_expr("'EQ' if {x} == {y} else 'NEQ'", x=1, y=2) == "NEQ" case = "case(({x} < 25, 'LOW'), ({x} > 75, 'HIGH'), (True, 'MEDIUM'))" - assert eval_expr(case, x=10) == 'LOW' - assert eval_expr(case, x=100) == 'HIGH' - assert eval_expr(case, x=50) == 'MEDIUM' - assert eval_expr('x', x='a') == 'a' - assert eval_expr('x+y', x=1, y=2) == 3 - assert eval_expr('x["a"] + y', x={'a': 1}, y=2) == 3 - assert eval_expr('x["a"]["b"] + y', x={'a': {'b': 1}}, y=2) == 3 - p = Person(name='x', aliases=['a', 'b', 'c'], address=Address(street='1 x street')) - assert eval_expr('p.name', p=p) == 'x' - assert eval_expr('p.address.street', p=p) == '1 x street' - assert eval_expr('len(p.aliases)', p=p) == 3 - assert eval_expr('p.aliases', p=p) == p.aliases - p2 = Person(name='x2', aliases=['a2', 'b2', 'c2'], address=Address(street='2 x street')) + assert eval_expr(case, x=10) == "LOW" + assert eval_expr(case, x=100) == "HIGH" + assert eval_expr(case, x=50) == "MEDIUM" + assert eval_expr("x", x="a") == "a" + assert eval_expr("x+y", x=1, y=2) == 3 + assert eval_expr('x["a"] + y', x={"a": 1}, y=2) == 3 + assert eval_expr('x["a"]["b"] + y', x={"a": {"b": 1}}, y=2) == 3 + p = Person(name="x", aliases=["a", "b", "c"], address=Address(street="1 x street")) + assert eval_expr("p.name", p=p) == "x" + assert eval_expr("p.address.street", p=p) == "1 x street" + assert eval_expr("len(p.aliases)", p=p) == 3 + assert eval_expr("p.aliases", p=p) == p.aliases + p2 = Person(name="x2", aliases=["a2", "b2", "c2"], address=Address(street="2 x street")) c = Container(persons=[p, p2]) - assert eval_expr('c.persons.name', c=c) == ['x', 'x2'] - assert eval_expr('c.persons.address.street', c=c) == ['1 x street', '2 x street'] - assert eval_expr('strlen(c.persons.address.street)', c=c) == [10, 10] + assert eval_expr("c.persons.name", c=c) == ["x", "x2"] + assert eval_expr("c.persons.address.street", c=c) == ["1 x street", "2 x street"] + assert eval_expr("strlen(c.persons.address.street)", c=c) == [10, 10] c = Container(person_index={p.name: p, p2.name: p2}) - assert eval_expr('c.person_index.name', c=c) == ['x', 'x2'] - assert eval_expr('c.person_index.address.street', c=c) == ['1 x street', '2 x street'] - assert eval_expr('strlen(c.person_index.name)', c=c) == [1, 2] - pd = dict(name='x', aliases=['a', 'b', 'c'], address=Address(street='1 x street')) - assert eval_expr('p.name', p=pd, _distribute=False) == 'x' + assert eval_expr("c.person_index.name", c=c) == ["x", "x2"] + assert eval_expr("c.person_index.address.street", c=c) == ["1 x street", "2 x street"] + assert eval_expr("strlen(c.person_index.name)", c=c) == [1, 2] + pd = dict(name="x", aliases=["a", "b", "c"], address=Address(street="1 x street")) + assert eval_expr("p.name", p=pd, _distribute=False) == "x" def test_no_eval_prohibited(): @@ -80,4 +80,4 @@ def test_no_eval_prohibited(): def test_funcs(): with pytest.raises(NotImplementedError): - eval_expr("my_func([1,2,3])") \ No newline at end of file + eval_expr("my_func([1,2,3])") diff --git a/tests/test_utils/test_formatutils.py b/tests/test_utils/test_formatutils.py index 46a45861..9c52d9aa 100644 --- a/tests/test_utils/test_formatutils.py +++ b/tests/test_utils/test_formatutils.py @@ -4,33 +4,42 @@ from jsonasobj2 import JsonObj, as_json -from linkml_runtime.utils.formatutils import camelcase, underscore, lcamelcase, be, split_line, wrapped_annotation, \ - is_empty, remove_empty_items, uncamelcase +from linkml_runtime.utils.formatutils import ( + be, + camelcase, + is_empty, + lcamelcase, + remove_empty_items, + split_line, + uncamelcase, + underscore, + wrapped_annotation, +) empty_things = [None, dict(), list(), JsonObj(), JsonObj({}), JsonObj([])] -non_empty_things = [0, False, "", {'k': None}, {0:0}, [None], JsonObj(k=None), JsonObj(**{'k': None}), JsonObj([None])] - -things_removed: list[tuple[Any, Any]] = \ - [(None, None), - (dict(), {}), - (list(), []), - (JsonObj(), {}), - (JsonObj({}), {}), - (JsonObj([]), []), - (0, 0), - (False, False), - ("", ""), - ({'k': None}, {}), - ({0:0}, {0:0}), - ([None], []), - (JsonObj(k=None), {}), - (JsonObj(**{'k': None}), {}), - (JsonObj([None]), []), - ([None], []), - ([None, None],[]), - ([None, [], [{}]], []), - ({"k": [{"l": None, "m": [None]}]}, {}) - ] +non_empty_things = [0, False, "", {"k": None}, {0: 0}, [None], JsonObj(k=None), JsonObj(**{"k": None}), JsonObj([None])] + +things_removed: list[tuple[Any, Any]] = [ + (None, None), + (dict(), {}), + (list(), []), + (JsonObj(), {}), + (JsonObj({}), {}), + (JsonObj([]), []), + (0, 0), + (False, False), + ("", ""), + ({"k": None}, {}), + ({0: 0}, {0: 0}), + ([None], []), + (JsonObj(k=None), {}), + (JsonObj(**{"k": None}), {}), + (JsonObj([None]), []), + ([None], []), + ([None, None], []), + ([None, [], [{}]], []), + ({"k": [{"l": None, "m": [None]}]}, {}), +] issue_157_1 = """ [ @@ -106,27 +115,49 @@ def test_formats(self): self.assertEqual("thisIsIt", lcamelcase(" this is\t it\n")) - self.assertEqual('abc', be(' abc\n')) - self.assertEqual('', be(None)) - self.assertEqual('', be(' ')) + self.assertEqual("abc", be(" abc\n")) + self.assertEqual("", be(None)) + self.assertEqual("", be(" ")) def test_linestuff(self): - text = "This is a mess'o test that goes on for a long way. It has some carriage\n returns embedded in it " \ - "but otherwise it drags on and on and on until the cows come home. Splitline covers this we hope." - self.assertEqual(["This is a mess'o test that goes on for a long way. It has some carriage returns embedded" - " in it but otherwise it ", - 'drags on and on and on until the cows come home. Splitline covers this we hope. '], - split_line(text)) - self.assertEqual(["This is a mess'o ", 'test that goes on ', 'for a long way. It ', 'has some carriage ', - 'returns embedded in ', 'it but otherwise it ', 'drags on and on and ', 'on until the cows ', - 'come home. ', 'Splitline covers ', 'this we hope. '], split_line(text, 20)) - self.assertEqual(['X' * 100 + ' '], split_line('X'*100, 20)) - self.assertEqual("""This is a mess'o test that goes on for a long way. It has some carriage + text = ( + "This is a mess'o test that goes on for a long way. It has some carriage\n returns embedded in it " + "but otherwise it drags on and on and on until the cows come home. Splitline covers this we hope." + ) + self.assertEqual( + [ + "This is a mess'o test that goes on for a long way. It has some carriage returns embedded" + " in it but otherwise it ", + "drags on and on and on until the cows come home. Splitline covers this we hope. ", + ], + split_line(text), + ) + self.assertEqual( + [ + "This is a mess'o ", + "test that goes on ", + "for a long way. It ", + "has some carriage ", + "returns embedded in ", + "it but otherwise it ", + "drags on and on and ", + "on until the cows ", + "come home. ", + "Splitline covers ", + "this we hope. ", + ], + split_line(text, 20), + ) + self.assertEqual(["X" * 100 + " "], split_line("X" * 100, 20)) + self.assertEqual( + """This is a mess'o test that goes on for a long way. It has some carriage returns embedded in it but otherwise it drags on and on and on until the cows come home. Splitline covers this we - hope. """, wrapped_annotation(text)) + hope. """, + wrapped_annotation(text), + ) def test_empty_functions(self): - """ Test the various forms of is_empty """ + """Test the various forms of is_empty""" for thing in empty_things: self.assertTrue(is_empty(thing), msg=f"{thing} should clock in as empty") for thing in non_empty_things: @@ -135,9 +166,9 @@ def test_empty_functions(self): assert is_empty(obj) def test_remove_empty_items(self): - """ Test the various remove empty items paths """ + """Test the various remove empty items paths""" seen = set() - save = list() # Keep garbage collection from re-using ids + save = list() # Keep garbage collection from re-using ids for thing, expected in things_removed: actual = remove_empty_items(thing) self.assertEqual(expected, actual, msg=f"Input = {thing}") @@ -149,14 +180,21 @@ def test_remove_empty_items(self): seen.add(id(actual)) def test_enumerations_case(self): - self.assertEqual("""[ + self.assertEqual( + """[ "state", "1" -]""", as_json(remove_empty_items(json.loads(issue_157_1), hide_protected_keys=True))) - self.assertEqual("""[ +]""", + as_json(remove_empty_items(json.loads(issue_157_1), hide_protected_keys=True)), + ) + self.assertEqual( + """[ "namedstate", "production" -]""", as_json(remove_empty_items(json.loads(issue_157_2), hide_protected_keys=True))) +]""", + as_json(remove_empty_items(json.loads(issue_157_2), hide_protected_keys=True)), + ) + -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_inference_utils.py b/tests/test_utils/test_inference_utils.py index caa636b2..a8048dba 100644 --- a/tests/test_utils/test_inference_utils.py +++ b/tests/test_utils/test_inference_utils.py @@ -2,19 +2,23 @@ import unittest from decimal import Decimal -from linkml_runtime.utils.inference_utils import infer_all_slot_values, generate_slot_value, infer_slot_value, Policy, \ - Config +from linkml_runtime.utils.inference_utils import ( + Config, + Policy, + generate_slot_value, + infer_all_slot_values, + infer_slot_value, +) from linkml_runtime.utils.schemaview import SchemaView - -from tests.test_utils.model.inference_example import Person, Container, Evil, Relationship, AgeEnum from tests.test_utils import INPUT_DIR +from tests.test_utils.model.inference_example import AgeEnum, Container, Evil, Person, Relationship -SCHEMA = os.path.join(INPUT_DIR, 'inference-example.yaml') +SCHEMA = os.path.join(INPUT_DIR, "inference-example.yaml") AGE_IN_YEARS = 12 -FIRST, LAST = 'x', 'y' -FULL = f'{FIRST} {LAST}' -REPLACE_ME = 'REPLACE ME' +FIRST, LAST = "x", "y" +FULL = f"{FIRST} {LAST}" +REPLACE_ME = "REPLACE ME" class InferenceUtilsTestCase(unittest.TestCase): @@ -28,7 +32,7 @@ def test_rstring_serialization(self): """ sv = SchemaView(SCHEMA) p = Person(first_name=FIRST, last_name=LAST) - v = generate_slot_value(p, 'full_name', sv) + v = generate_slot_value(p, "full_name", sv) def test_string_serialization(self): """ @@ -36,9 +40,9 @@ def test_string_serialization(self): """ sv = SchemaView(SCHEMA) p = Person(first_name=FIRST, last_name=LAST) - v = generate_slot_value(p, 'full_name', sv) + v = generate_slot_value(p, "full_name", sv) self.assertEqual(v, FULL) - infer_slot_value(p, 'full_name', sv) + infer_slot_value(p, "full_name", sv) self.assertEqual(p.full_name, FULL) p = Person(first_name=FIRST, last_name=LAST) infer_all_slot_values(p, schemaview=sv) @@ -110,12 +114,12 @@ def test_infer_expressions(self): config = Config(use_expressions=True) infer_all_slot_values(p, schemaview=sv, config=config) assert p.is_juvenile - self.assertEqual(p.age_category, AgeEnum('juvenile')) + self.assertEqual(p.age_category, AgeEnum("juvenile")) self.assertEqual(p.age_category.code, AgeEnum.juvenile) - #e1 = AgeEnum('juvenile') - #e2 = AgeEnum.juvenile - #print(f'e1={e1} c={e1.code} t={type(e1)}') - #print(f'e2={e2} {type(e2)}') + # e1 = AgeEnum('juvenile') + # e2 = AgeEnum.juvenile + # print(f'e1={e1} c={e1.code} t={type(e1)}') + # print(f'e2={e2} {type(e2)}') # test slots with spaces p = Person(slot_with_spaces="test") infer_all_slot_values(p, schemaview=sv, config=config) @@ -123,17 +127,17 @@ def test_infer_expressions(self): def test_if_then(self): sv = SchemaView(SCHEMA) - p = Person(first_name='x', last_name='y', age_in_years=Decimal(AGE_IN_YEARS)) + p = Person(first_name="x", last_name="y", age_in_years=Decimal(AGE_IN_YEARS)) config = Config(use_expressions=True) infer_all_slot_values(p, schemaview=sv, config=config) - self.assertEqual(p.summary, f'xy AGE: {AGE_IN_YEARS}') - p = Person(first_name='x', last_name='y') + self.assertEqual(p.summary, f"xy AGE: {AGE_IN_YEARS}") + p = Person(first_name="x", last_name="y") infer_all_slot_values(p, schemaview=sv, config=config) - self.assertEqual(p.summary, 'xy NO AGE SPECIFIED') + self.assertEqual(p.summary, "xy NO AGE SPECIFIED") def test_custom_function(self): sv = SchemaView(SCHEMA) - p = Person(first_name='abc', last_name='def', age_in_years=Decimal(AGE_IN_YEARS)) + p = Person(first_name="abc", last_name="def", age_in_years=Decimal(AGE_IN_YEARS)) config = Config(resolve_function=lambda x, _: f'"{x.upper()}"' if isinstance(x, str) else x) infer_all_slot_values(p, schemaview=sv, config=config) self.assertEqual(p.full_name, '"ABC" "DEF"') @@ -152,19 +156,18 @@ def test_protect_against_evil(self): with self.assertRaises(NotImplementedError): infer_all_slot_values(p, schemaview=sv, config=config, policy=policy) - def test_nesting(self): """ Tests use of nested variables """ sv = SchemaView(SCHEMA) - p1 = Person(first_name='a', last_name='b') - p2 = Person(first_name='c', last_name='d') - r = Relationship(person1=p1, person2=p2, type='SIBLING_OF') + p1 = Person(first_name="a", last_name="b") + p2 = Person(first_name="c", last_name="d") + r = Relationship(person1=p1, person2=p2, type="SIBLING_OF") infer_all_slot_values(r, schemaview=sv) self.assertEqual('"b, a" IS SIBLING_OF "d, c"', r.description) self.assertEqual('"a b" IS SIBLING_OF "c d"', r.description2) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_inlined_as_dict_forms.py b/tests/test_utils/test_inlined_as_dict_forms.py index 01aa4ac1..ebbf476c 100644 --- a/tests/test_utils/test_inlined_as_dict_forms.py +++ b/tests/test_utils/test_inlined_as_dict_forms.py @@ -6,7 +6,8 @@ class InlinedAsDictTestcase(unittest.TestCase): - """ Test the various YAML forms for inlined_as_dict entries""" + """Test the various YAML forms for inlined_as_dict entries""" + def test_list_variations(self): v = E() self.assertEqual(v.ev, {}, "No entries, period") @@ -19,89 +20,115 @@ def test_list_variations(self): # Form 5 -- list of keys v1 = JsonObj(["k1", "k2"]) v = E(v1) - self.assertEqual(v.ev, {'k1': EInst(s1='k1'), 'k2': EInst(s1='k2')}) + self.assertEqual(v.ev, {"k1": EInst(s1="k1"), "k2": EInst(s1="k2")}) # Form 4: -- list of key/object pairs - v = E([{"k1": {"s1": "k1", "s2": "v21", "s3": "v23"}}, - {"k2": {"s2": "v22", "s3": "v23"}}, - {"k3": {}}]) - self.assertEqual(v.ev, - {'k1': EInst(s1='k1', s2='v21', s3='v23'), - 'k2': EInst(s1='k2', s2='v22', s3='v23'), - 'k3': EInst(s1='k3', s2=None, s3=None)}, - "List of key value constructors") + v = E([{"k1": {"s1": "k1", "s2": "v21", "s3": "v23"}}, {"k2": {"s2": "v22", "s3": "v23"}}, {"k3": {}}]) + self.assertEqual( + v.ev, + { + "k1": EInst(s1="k1", s2="v21", s3="v23"), + "k2": EInst(s1="k2", s2="v22", s3="v23"), + "k3": EInst(s1="k3", s2=None, s3=None), + }, + "List of key value constructors", + ) with self.assertRaises(ValueError) as e: E([{"k1": None}, {"k1": "v2"}]) self.assertIn("k1: duplicate key", str(e.exception)) with self.assertRaises(ValueError) as e: - E([{"k1": {"s1":"k2"}}]) + E([{"k1": {"s1": "k2"}}]) self.assertIn("Slot: ev - attribute s1 value (k2) does not match key (k1)", str(e.exception)) # Form 5 variations - v = E([{"k1": EInst(s1="k1", s2="v21", s3="v23")}, - {"k2": JsonObj({"s2": "v22", "s3": "v23"})}, - {"k3": None}]) - self.assertEqual(v.ev, - { - 'k1': EInst(s1='k1', s2='v21', s3='v23'), - 'k2': EInst(s1='k2', s2='v22', s3='v23'), - 'k3': EInst(s1='k3', s2=None, s3=None) - }) + v = E([{"k1": EInst(s1="k1", s2="v21", s3="v23")}, {"k2": JsonObj({"s2": "v22", "s3": "v23"})}, {"k3": None}]) + self.assertEqual( + v.ev, + { + "k1": EInst(s1="k1", s2="v21", s3="v23"), + "k2": EInst(s1="k2", s2="v22", s3="v23"), + "k3": EInst(s1="k3", s2=None, s3=None), + }, + ) # More Form 5 variations v = E(["k1", "k2", {"k3": "v3"}, ["k4", "v4"], {"s1": "k5", "s2": "v52"}]) - self.assertEqual(v.ev, - {'k1': EInst(s1='k1', s2=None, s3=None), - 'k2': EInst(s1='k2', s2=None, s3=None), - 'k3': EInst(s1='k3', s2='v3', s3=None), - 'k4': EInst(s1='k4', s2='v4', s3=None), - 'k5': EInst(s1='k5', s2='v52', s3=None)}, "Key value tuples") + self.assertEqual( + v.ev, + { + "k1": EInst(s1="k1", s2=None, s3=None), + "k2": EInst(s1="k2", s2=None, s3=None), + "k3": EInst(s1="k3", s2="v3", s3=None), + "k4": EInst(s1="k4", s2="v4", s3=None), + "k5": EInst(s1="k5", s2="v52", s3=None), + }, + "Key value tuples", + ) # Form 6 - list of positional object values v = E([["k1", "v12", "v13"], ["k2", "v22"], ["k3"]]) - self.assertEqual(v.ev, - {'k1': EInst(s1='k1', s2='v12', s3='v13'), - 'k2': EInst(s1='k2', s2='v22', s3=None), - 'k3': EInst(s1='k3', s2=None, s3=None)}, "Positional objects") + self.assertEqual( + v.ev, + { + "k1": EInst(s1="k1", s2="v12", s3="v13"), + "k2": EInst(s1="k2", s2="v22", s3=None), + "k3": EInst(s1="k3", s2=None, s3=None), + }, + "Positional objects", + ) # Form 7 - list of kv dictionaries v = E([{"s1": "v11", "s2": "v12"}, {"s1": "v21", "s2": "v22", "s3": "v23"}]) - self.assertEqual(v.ev, - {'v11': EInst(s1='v11', s2='v12', s3=None), - 'v21': EInst(s1='v21', s2='v22', s3='v23')}, "List of dictionaries") - + self.assertEqual( + v.ev, + {"v11": EInst(s1="v11", s2="v12", s3=None), "v21": EInst(s1="v21", s2="v22", s3="v23")}, + "List of dictionaries", + ) def test_dict_variations(self): - """ Test various forms of inlined as dict entries """ + """Test various forms of inlined as dict entries""" # Form 1: key / object - v = E({"k1": EInst(s1="k1", s2="v21", s3="v23"), - "k2": JsonObj({"s2": "v22", "s3": "v23"}), - "k3": {"s2": "v32", "s3": "v33"}, - "k4": {"s1": "k4"}}) - self.assertEqual(v.ev, - {'k1': EInst(s1='k1', s2='v21', s3='v23'), - 'k2': EInst(s1='k2', s2='v22', s3='v23'), - 'k3': EInst(s1='k3', s2='v32', s3='v33'), - 'k4': EInst(s1='k4', s2=None, s3=None)}, - "Dictionary of key/object entries") + v = E( + { + "k1": EInst(s1="k1", s2="v21", s3="v23"), + "k2": JsonObj({"s2": "v22", "s3": "v23"}), + "k3": {"s2": "v32", "s3": "v33"}, + "k4": {"s1": "k4"}, + } + ) + self.assertEqual( + v.ev, + { + "k1": EInst(s1="k1", s2="v21", s3="v23"), + "k2": EInst(s1="k2", s2="v22", s3="v23"), + "k3": EInst(s1="k3", s2="v32", s3="v33"), + "k4": EInst(s1="k4", s2=None, s3=None), + }, + "Dictionary of key/object entries", + ) # Form 2: key/value tuples (only works when at most two values are required v = E(ev={"k1": "v11", "k2": "v21", "k3": {}}) - expected = ("E({ 'ev': { 'k1': {'s1': 'k1', 's2': 'v11'},\n" - " 'k2': {'s1': 'k2', 's2': 'v21'},\n" - " 'k3': {'s1': 'k3'}}})") - self.assertEqual(v.ev, - {'k1': EInst(s1='k1', s2='v11', s3=None), - 'k2': EInst(s1='k2', s2='v21', s3=None), - 'k3': EInst(s1='k3', s2=None, s3=None)}, - "Dictionary of two-key entries") + expected = ( + "E({ 'ev': { 'k1': {'s1': 'k1', 's2': 'v11'},\n" + " 'k2': {'s1': 'k2', 's2': 'v21'},\n" + " 'k3': {'s1': 'k3'}}})" + ) + self.assertEqual( + v.ev, + { + "k1": EInst(s1="k1", s2="v11", s3=None), + "k2": EInst(s1="k2", s2="v21", s3=None), + "k3": EInst(s1="k3", s2=None, s3=None), + }, + "Dictionary of two-key entries", + ) # Form 3: Basic single object (differentiated from form2 by the presence of the key name v = E({"s1": "k1"}) - self.assertEqual(v.ev, {'k1': EInst(s1='k1', s2=None, s3=None)}, - "Single entry dictionary") + self.assertEqual(v.ev, {"k1": EInst(s1="k1", s2=None, s3=None)}, "Single entry dictionary") v = E({"s1": "k1", "s2": "v12"}) - self.assertEqual(v.ev, {'k1': EInst(s1='k1', s2='v12', s3=None)}, "Single entry dictionary") + self.assertEqual(v.ev, {"k1": EInst(s1="k1", s2="v12", s3=None)}, "Single entry dictionary") def test_isempties(self): base = E() @@ -112,11 +139,9 @@ def test_isempties(self): self.assertTrue(base._is_empty(JsonObj([]))) self.assertFalse(base._is_empty(0)) self.assertFalse(base._is_empty("")) - self.assertFalse(base._is_empty(JsonObj({'k': 0}))) + self.assertFalse(base._is_empty(JsonObj({"k": 0}))) self.assertFalse(base._is_empty(JsonObj([None]))) - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() - diff --git a/tests/test_utils/test_inlined_as_list_forms.py b/tests/test_utils/test_inlined_as_list_forms.py index 6c606097..a69a210d 100644 --- a/tests/test_utils/test_inlined_as_list_forms.py +++ b/tests/test_utils/test_inlined_as_list_forms.py @@ -6,7 +6,8 @@ class InlinedAsListTestcase(unittest.TestCase): - """ Test the various YAML forms for inlined_as_list entries""" + """Test the various YAML forms for inlined_as_list entries""" + def test_list_variations(self): v = E() self.assertEqual(v.ev, [], "No entries, period") @@ -19,83 +20,93 @@ def test_list_variations(self): # Form 5 -- list of keys v1 = JsonObj(["k1", "k2"]) v = E(v1) - self.assertEqual(v.ev, [EInst(s1='k1', s2=None, s3=None), EInst(s1='k2', s2=None, s3=None)]) + self.assertEqual(v.ev, [EInst(s1="k1", s2=None, s3=None), EInst(s1="k2", s2=None, s3=None)]) # Form 4: -- list of key/object pairs - v = E([{"k1": {"s1": "k1", "s2": "v21", "s3": "v23"}}, - {"k2": {"s2": "v22", "s3": "v23"}}, - {"k3": {}}]) - self.assertEqual(v.ev, - [EInst(s1='k1', s2='v21', s3='v23'), - EInst(s1='k2', s2='v22', s3='v23'), - EInst(s1='k3', s2=None, s3=None)], - "List of key value constructors") + v = E([{"k1": {"s1": "k1", "s2": "v21", "s3": "v23"}}, {"k2": {"s2": "v22", "s3": "v23"}}, {"k3": {}}]) + self.assertEqual( + v.ev, + [EInst(s1="k1", s2="v21", s3="v23"), EInst(s1="k2", s2="v22", s3="v23"), EInst(s1="k3", s2=None, s3=None)], + "List of key value constructors", + ) with self.assertRaises(ValueError) as e: E([{"k1": None}, {"k1": "v2"}]) self.assertIn("k1: duplicate key", str(e.exception)) with self.assertRaises(ValueError) as e: - E([{"k1": {"s1":"k2"}}]) + E([{"k1": {"s1": "k2"}}]) self.assertIn("Slot: ev - attribute s1 value (k2) does not match key (k1)", str(e.exception)) # Form 5 variations - v = E([{"k1": EInst(s1="k1", s2="v21", s3="v23")}, - {"k2": JsonObj({"s2": "v22", "s3": "v23"})}, - {"k3": None}]) - self.assertEqual(v.ev, - [EInst(s1='k1', s2='v21', s3='v23'), - EInst(s1='k2', s2='v22', s3='v23'), - EInst(s1='k3', s2=None, s3=None)]) + v = E([{"k1": EInst(s1="k1", s2="v21", s3="v23")}, {"k2": JsonObj({"s2": "v22", "s3": "v23"})}, {"k3": None}]) + self.assertEqual( + v.ev, + [EInst(s1="k1", s2="v21", s3="v23"), EInst(s1="k2", s2="v22", s3="v23"), EInst(s1="k3", s2=None, s3=None)], + ) # More Form 5 variations v = E(["k1", "k2", {"k3": "v3"}, ["k4", "v4"], {"s1": "k5", "s2": "v52"}]) - self.assertEqual(v.ev, - [EInst(s1='k1', s2=None, s3=None), - EInst(s1='k2', s2=None, s3=None), - EInst(s1='k3', s2='v3', s3=None), - EInst(s1='k4', s2='v4', s3=None), - EInst(s1='k5', s2='v52', s3=None)], "Key value tuples") + self.assertEqual( + v.ev, + [ + EInst(s1="k1", s2=None, s3=None), + EInst(s1="k2", s2=None, s3=None), + EInst(s1="k3", s2="v3", s3=None), + EInst(s1="k4", s2="v4", s3=None), + EInst(s1="k5", s2="v52", s3=None), + ], + "Key value tuples", + ) # Form 6 - list of positional object values v = E([["k1", "v12", "v13"], ["k2", "v22"], ["k3"]]) - self.assertEqual(v.ev, - [EInst(s1='k1', s2='v12', s3='v13'), - EInst(s1='k2', s2='v22', s3=None), - EInst(s1='k3', s2=None, s3=None)], "Positional objects") + self.assertEqual( + v.ev, + [EInst(s1="k1", s2="v12", s3="v13"), EInst(s1="k2", s2="v22", s3=None), EInst(s1="k3", s2=None, s3=None)], + "Positional objects", + ) # Form 7 - list of kv dictionaries v = E([{"s1": "v11", "s2": "v12"}, {"s1": "v21", "s2": "v22", "s3": "v23"}]) - self.assertEqual(v.ev, - [EInst(s1='v11', s2='v12', s3=None), - EInst(s1='v21', s2='v22', s3='v23')], "List of dictionaries") - + self.assertEqual( + v.ev, [EInst(s1="v11", s2="v12", s3=None), EInst(s1="v21", s2="v22", s3="v23")], "List of dictionaries" + ) def test_dict_variations(self): - """ Test various forms of inlined as list entries """ + """Test various forms of inlined as list entries""" # Form 1: key / object - v = E({"k1": EInst(s1="k1", s2="v21", s3="v23"), - "k2": JsonObj({"s2": "v22", "s3": "v23"}), - "k3": {"s2": "v32", "s3": "v33"}, - "k4": {"s1": "k4"}}) - self.assertEqual(v.ev, - [EInst(s1='k1', s2='v21', s3='v23'), - EInst(s1='k2', s2='v22', s3='v23'), - EInst(s1='k3', s2='v32', s3='v33'), - EInst(s1='k4', s2=None, s3=None)], "Dictionary of key/object entries") + v = E( + { + "k1": EInst(s1="k1", s2="v21", s3="v23"), + "k2": JsonObj({"s2": "v22", "s3": "v23"}), + "k3": {"s2": "v32", "s3": "v33"}, + "k4": {"s1": "k4"}, + } + ) + self.assertEqual( + v.ev, + [ + EInst(s1="k1", s2="v21", s3="v23"), + EInst(s1="k2", s2="v22", s3="v23"), + EInst(s1="k3", s2="v32", s3="v33"), + EInst(s1="k4", s2=None, s3=None), + ], + "Dictionary of key/object entries", + ) # Form 2: key/value tuples (only works when at most two values are required v = E(ev={"k1": "v11", "k2": "v21", "k3": {}}) - self.assertEqual(v.ev, - [EInst(s1='k1', s2='v11', s3=None), - EInst(s1='k2', s2='v21', s3=None), - EInst(s1='k3', s2=None, s3=None)], "Dictionary of two-key entries") + self.assertEqual( + v.ev, + [EInst(s1="k1", s2="v11", s3=None), EInst(s1="k2", s2="v21", s3=None), EInst(s1="k3", s2=None, s3=None)], + "Dictionary of two-key entries", + ) # Form 3: Basic single object (differentiated from form2 by the presence of the key name v = E({"s1": "k1"}) - self.assertEqual(v.ev, [EInst(s1='k1', s2=None, s3=None)], - "Single entry dictionary") + self.assertEqual(v.ev, [EInst(s1="k1", s2=None, s3=None)], "Single entry dictionary") v = E({"s1": "k1", "s2": "v12"}) - self.assertEqual(v.ev, [EInst(s1='k1', s2='v12', s3=None)], "Single entry dictionary") + self.assertEqual(v.ev, [EInst(s1="k1", s2="v12", s3=None)], "Single entry dictionary") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_introspection.py b/tests/test_utils/test_introspection.py index 959d7ed2..21588b6a 100644 --- a/tests/test_utils/test_introspection.py +++ b/tests/test_utils/test_introspection.py @@ -1,22 +1,21 @@ import unittest from linkml_runtime.linkml_model import SchemaDefinition -from linkml_runtime.utils.introspection import package_schemaview, object_class_definition +from linkml_runtime.utils.introspection import object_class_definition, package_schemaview class IntrospectionTestCase(unittest.TestCase): def test_introspection_on_metamodel(self): - view = package_schemaview('linkml_runtime.linkml_model.meta') - for cn in ['class_definition', 'type_definition', 'slot_definition']: + view = package_schemaview("linkml_runtime.linkml_model.meta") + for cn in ["class_definition", "type_definition", "slot_definition"]: assert cn in view.all_classes() - for tn in ['uriorcurie', 'string', 'float']: + for tn in ["uriorcurie", "string", "float"]: assert tn in view.all_types() - obj = SchemaDefinition(id='x', name='x') + obj = SchemaDefinition(id="x", name="x") c = object_class_definition(obj) - assert 'classes' in c.slots + assert "classes" in c.slots - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_list_strings.py b/tests/test_utils/test_list_strings.py index eff183a0..9690128b 100644 --- a/tests/test_utils/test_list_strings.py +++ b/tests/test_utils/test_list_strings.py @@ -1,7 +1,7 @@ import unittest -from linkml_runtime.loaders import yaml_loader from linkml_runtime.linkml_model.meta import SchemaDefinition +from linkml_runtime.loaders import yaml_loader sample = """id: http://examples.org/test name: test @@ -39,11 +39,11 @@ class ListStringsTestCase(unittest.TestCase): def test_strings_in_list_slot(self): rslt = yaml_loader.loads(sample, SchemaDefinition) - self.assertEqual(1, len(rslt.classes['AClass'].slots)) - self.assertEqual('a_slot', rslt.classes['AClass'].slots[0]) - self.assertEqual(1, len(rslt.classes['BClass'].mixins)) - self.assertEqual('AClass', rslt.classes['BClass'].mixins[0]) + self.assertEqual(1, len(rslt.classes["AClass"].slots)) + self.assertEqual("a_slot", rslt.classes["AClass"].slots[0]) + self.assertEqual(1, len(rslt.classes["BClass"].mixins)) + self.assertEqual("AClass", rslt.classes["BClass"].mixins[0]) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_metamodelcore.py b/tests/test_utils/test_metamodelcore.py index b4151ea1..41029b84 100644 --- a/tests/test_utils/test_metamodelcore.py +++ b/tests/test_utils/test_metamodelcore.py @@ -3,10 +3,19 @@ from dataclasses import dataclass from jsonasobj2 import as_json -from rdflib import Literal, XSD, Graph, RDF, Namespace +from rdflib import RDF, XSD, Graph, Literal, Namespace -from linkml_runtime.utils.metamodelcore import NCName, Bool, URIorCURIE, URI, XSDDate, XSDDateTime, XSDTime, Curie, \ - NodeIdentifier +from linkml_runtime.utils.metamodelcore import ( + URI, + Bool, + Curie, + NCName, + NodeIdentifier, + URIorCURIE, + XSDDate, + XSDDateTime, + XSDTime, +) from linkml_runtime.utils.namespaces import Namespaces from linkml_runtime.utils.strictness import lax, strict from linkml_runtime.utils.yamlutils import YAMLRoot, as_rdf @@ -17,9 +26,9 @@ def tearDown(self) -> None: strict() def test_ncname(self): - self.assertEqual('A123', NCName('A123')) - x = NCName('A1.B_C-') - self.assertEqual('A1.B_C-', x) + self.assertEqual("A123", NCName("A123")) + x = NCName("A1.B_C-") + self.assertEqual("A1.B_C-", x) self.assertIsInstance(x, str) self.assertIsInstance(x, NCName) self.assertEqual(x, NCName(x)) @@ -27,12 +36,12 @@ def test_ncname(self): self.assertIsInstance(x, str) self.assertFalse(isinstance(x, NCName)) with self.assertRaises(ValueError): - NCName('1') + NCName("1") with self.assertRaises(ValueError): - NCName('A12!') + NCName("A12!") def test_uriorcuries(self): - """ Test the URI and URIorCURIE types """ + """Test the URI and URIorCURIE types""" str1 = "https://google.com/test#file?abc=1&def=4" self.assertEqual(str1, URIorCURIE(str1)) str2 = "abc:123" @@ -58,30 +67,29 @@ def test_uriorcuries(self): self.assertFalse(URIorCURIE.is_curie("http://example.org/path")) def test_curie(self): - """ Test the CURIE type """ + """Test the CURIE type""" self.assertEqual("rdf:type", Curie("rdf:type")) with self.assertRaises(ValueError): Curie("type") self.assertFalse(Curie.is_valid("type")) self.assertEqual(":type", Curie(":type")) - self.assertTrue(Curie.is_valid(':type')) - self.assertTrue(Curie.is_valid('WIKIDATA_PROPERTY:P854')) - self.assertTrue(Curie.is_valid('WIKIDATA.PROPERTY:P854')) - self.assertTrue(Curie.is_valid('CL:0000001')) + self.assertTrue(Curie.is_valid(":type")) + self.assertTrue(Curie.is_valid("WIKIDATA_PROPERTY:P854")) + self.assertTrue(Curie.is_valid("WIKIDATA.PROPERTY:P854")) + self.assertTrue(Curie.is_valid("CL:0000001")) with self.assertRaises(ValueError): Curie("1df:type") - self.assertFalse(Curie.is_valid('1df:type')) - self.assertTrue(Curie.is_valid('rdf:17')) + self.assertFalse(Curie.is_valid("1df:type")) + self.assertTrue(Curie.is_valid("rdf:17")) nsm = Namespaces(Graph()) self.assertEqual(RDF.type, Curie("rdf:type").as_uri(nsm)) self.assertIsNone(Curie("ex:foo").as_uri(nsm)) self.assertIsNone(Curie(":bar").as_uri(nsm)) nsm._default = "http://example.org/test#" - self.assertEqual(nsm._default['bear'], Curie(":bear").as_uri(nsm)) - + self.assertEqual(nsm._default["bear"], Curie(":bear").as_uri(nsm)) def test_uri(self): - """ Test the URI data type """ + """Test the URI data type""" str1 = "https://google.com/test#file?abc=1&def=4" self.assertEqual(str1, URI(str1)) self.assertEqual("http://foo.org/bargles", URI("http://foo.org/bargles")) @@ -90,18 +98,20 @@ def test_uri(self): with self.assertRaises(ValueError): URI(":123") # imports range is uriorcurie, so we allow file paths - #URI("1") + # URI("1") self.assertTrue(URI.is_valid("foo.bar")) self.assertTrue(URI.is_valid("../a/b")) self.assertTrue(URI.is_valid("abc:123")) - #with self.assertRaises(ValueError): + # with self.assertRaises(ValueError): # URI("x1") # an empty URI is a valid same-document URI reference self.assertTrue(URI.is_valid("")) x = URI("rdf:type") self.assertTrue(URI.is_valid(x)) self.assertTrue(URI.is_valid("urn:abc:123")) - self.assertTrue(URI.is_valid("https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top")) + self.assertTrue( + URI.is_valid("https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top") + ) self.assertTrue(URI.is_valid("ldap://[2001:db8::7]/c=GB?objectClass?one")) self.assertTrue(URI.is_valid("ldap://[2001:db8::7]/c=GB?objectClass?one")) self.assertTrue(URI.is_valid("mailto:John.Doe@example.com")) @@ -139,68 +149,68 @@ def test_bool(self): def test_time(self): v = datetime.time(13, 17, 43, 279000) - self.assertEqual('13:17:43.279000', XSDTime(v)) # A date can be a datetime - self.assertEqual('13:17:43.279000', XSDTime(Literal(v, datatype=XSD.time))) # An RDFLIB Literal - self.assertEqual('13:17:43.279000', v.isoformat()) # A string - self.assertEqual('13:17:43.279000', XSDTime(XSDTime(v))) # An existing date + self.assertEqual("13:17:43.279000", XSDTime(v)) # A date can be a datetime + self.assertEqual("13:17:43.279000", XSDTime(Literal(v, datatype=XSD.time))) # An RDFLIB Literal + self.assertEqual("13:17:43.279000", v.isoformat()) # A string + self.assertEqual("13:17:43.279000", XSDTime(XSDTime(v))) # An existing date strict() with self.assertRaises(ValueError): - XSDTime('Jan 12, 2019') + XSDTime("Jan 12, 2019") with self.assertRaises(ValueError): XSDTime(datetime.datetime.now()) lax() - self.assertEqual('Jan 12, 2019', XSDTime('Jan 12, 2019')) + self.assertEqual("Jan 12, 2019", XSDTime("Jan 12, 2019")) XSDDate(datetime.datetime.now()) - self.assertFalse(XSDTime.is_valid('Jan 12, 2019')) + self.assertFalse(XSDTime.is_valid("Jan 12, 2019")) self.assertFalse(XSDTime.is_valid(datetime.datetime.now())) self.assertFalse(XSDTime.is_valid("2019-07-06T17:22:39Z")) self.assertTrue(XSDTime.is_valid(v)) def test_date(self): v = datetime.date(2019, 7, 6) - self.assertEqual('2019-07-06', XSDDate(v)) # A date can be a datetime - self.assertEqual('2019-07-06', XSDDate(Literal(v, datatype=XSD.date))) # An RDFLIB Literal - self.assertEqual('2019-07-06', v.isoformat()) # A string - self.assertEqual('2019-07-06', XSDDate(XSDDate(v))) # An existing date + self.assertEqual("2019-07-06", XSDDate(v)) # A date can be a datetime + self.assertEqual("2019-07-06", XSDDate(Literal(v, datatype=XSD.date))) # An RDFLIB Literal + self.assertEqual("2019-07-06", v.isoformat()) # A string + self.assertEqual("2019-07-06", XSDDate(XSDDate(v))) # An existing date strict() with self.assertRaises(ValueError): - XSDDate('20190706') + XSDDate("20190706") with self.assertRaises(ValueError): - XSDDate('Jan 12, 2019') + XSDDate("Jan 12, 2019") with self.assertRaises(ValueError): XSDDate(datetime.datetime.now()) with self.assertRaises(ValueError): XSDDate("2019-07-06T17:22:39Z") lax() - bv = XSDDate('Jan 12, 2019') - self.assertEqual('Jan 12, 2019', bv) + bv = XSDDate("Jan 12, 2019") + self.assertEqual("Jan 12, 2019", bv) self.assertFalse(XSDDate.is_valid(bv)) XSDDate(datetime.datetime.now()) - self.assertFalse(XSDDate.is_valid('Jan 12, 2019')) + self.assertFalse(XSDDate.is_valid("Jan 12, 2019")) self.assertFalse(XSDDate.is_valid(datetime.datetime.now())) self.assertTrue(XSDDate.is_valid(XSDDate(datetime.datetime.now().date()))) self.assertTrue(XSDDate.is_valid(v)) def test_datetime(self): v = datetime.datetime(2019, 7, 6, 17, 22, 39, 7300) - self.assertEqual('2019-07-06T17:22:39.007300', XSDDateTime(v)) - self.assertEqual('2019-07-06T17:22:39.007300', XSDDateTime(Literal(v, datatype=XSD.dateTime))) - self.assertEqual('2019-07-06T17:22:39.007300', XSDDateTime(Literal(v).value)) - self.assertEqual('2019-07-06T17:22:39.007300', v.isoformat()) - self.assertEqual('2019-07-06T17:22:39.007300', XSDDateTime(XSDDateTime(v))) + self.assertEqual("2019-07-06T17:22:39.007300", XSDDateTime(v)) + self.assertEqual("2019-07-06T17:22:39.007300", XSDDateTime(Literal(v, datatype=XSD.dateTime))) + self.assertEqual("2019-07-06T17:22:39.007300", XSDDateTime(Literal(v).value)) + self.assertEqual("2019-07-06T17:22:39.007300", v.isoformat()) + self.assertEqual("2019-07-06T17:22:39.007300", XSDDateTime(XSDDateTime(v))) vstr = str(Literal(v).value) - self.assertEqual('2019-07-06 17:22:39.007300', vstr) # Note that this has no 'T' - self.assertEqual('2019-07-06T17:22:39.007300', XSDDateTime(vstr)) - self.assertEqual('2019-07-06T17:22:39+00:00', XSDDateTime("2019-07-06T17:22:39Z")) - self.assertEqual('2019-07-06T00:00:00', XSDDateTime("2019-07-06")) # Date as datetime + self.assertEqual("2019-07-06 17:22:39.007300", vstr) # Note that this has no 'T' + self.assertEqual("2019-07-06T17:22:39.007300", XSDDateTime(vstr)) + self.assertEqual("2019-07-06T17:22:39+00:00", XSDDateTime("2019-07-06T17:22:39Z")) + self.assertEqual("2019-07-06T00:00:00", XSDDateTime("2019-07-06")) # Date as datetime with self.assertRaises(ValueError): - XSDDateTime('Jan 12, 2019') + XSDDateTime("Jan 12, 2019") lax() - self.assertEqual('penguins', XSDDateTime('penguins')) + self.assertEqual("penguins", XSDDateTime("penguins")) XSDDateTime(datetime.datetime.now()) - self.assertFalse(XSDDateTime.is_valid('Jan 12, 2019')) + self.assertFalse(XSDDateTime.is_valid("Jan 12, 2019")) self.assertTrue(XSDDateTime.is_valid(datetime.datetime.now())) self.assertTrue(XSDDateTime.is_valid(XSDDate(datetime.datetime.now().date()))) self.assertTrue(XSDDateTime.is_valid(v)) @@ -228,6 +238,7 @@ def test_nodeidentifier(self): } }""" EX = Namespace("http://example.org/tests/") + class Root(NodeIdentifier): pass @@ -258,11 +269,15 @@ def __post_init__(self): s = Desc1(EX.descendant1) t = Child2(EX.child2) y = Pair(s, t) - self.assertEqual("""{ + self.assertEqual( + """{ "s": "http://example.org/tests/descendant1", "t": "http://example.org/tests/child2" -}""", as_json(y)) - self.assertEqual("""@prefix OIO: . +}""", + as_json(y), + ) + self.assertEqual( + """@prefix OIO: . @prefix dcterms: . @prefix metatype: . @prefix owl: . @@ -277,12 +292,12 @@ def __post_init__(self): rdfs:object "http://example.org/tests/child2" ; rdfs:subject "http://example.org/tests/descendant1" . -""", as_rdf(y, context).serialize(format="turtle")) +""", + as_rdf(y, context).serialize(format="turtle"), + ) with self.assertRaises(ValueError): y = Pair(s, s) - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_namespaces.py b/tests/test_utils/test_namespaces.py index fe08fc91..c185227b 100644 --- a/tests/test_utils/test_namespaces.py +++ b/tests/test_utils/test_namespaces.py @@ -9,16 +9,16 @@ class NamespacesTestCase(unittest.TestCase): def test_namespaces(self): ns = Namespaces() - ns['meta'] = "https://w3id.org/biolink/metamodel/" + ns["meta"] = "https://w3id.org/biolink/metamodel/" ns.skos = SKOS self.assertEqual(str(ns.skos), str(SKOS)) self.assertEqual(ns.skos.note, SKOS.note) ns.OIO = URIRef("http://www.geneontology.org/formats/oboInOwl") - ns['dc'] = "http://example.org/dc/" # Overrides 'dc' in semweb_context - ns['l1'] = "http://example.org/subset/" - ns['l2'] = "http://example.org/subset/test/" - ns['l3'] = "http://example.org/subset/t" - ns['u1'] = "urn:example:" + ns["dc"] = "http://example.org/dc/" # Overrides 'dc' in semweb_context + ns["l1"] = "http://example.org/subset/" + ns["l2"] = "http://example.org/subset/test/" + ns["l3"] = "http://example.org/subset/t" + ns["u1"] = "urn:example:" # This is now a warning instead of a value error # with self.assertRaises(ValueError): # ns['OIO'] = URIRef("http://www.geneontology.org/formats/another") @@ -33,15 +33,15 @@ def test_namespaces(self): ns.FOO self.assertEqual("'foo'", str(e.exception), "Unknown namespace should raise a KeyError with a lower case entry") - ns._default = ns['meta'] - ns._default = ns['meta'] + ns._default = ns["meta"] + ns._default = ns["meta"] with self.assertRaises(ValueError): ns._default = "http://example.org/wrong/" del ns._default with self.assertRaises(KeyError): del ns._default self.assertIsNone(ns._default) - ns._default = ns['meta'] + ns._default = ns["meta"] ns._base = "http://example.org/base/" ns._base = "http://example.org/base/" @@ -52,30 +52,30 @@ def test_namespaces(self): del ns._base ns._base = "http://example.org/wrong/" del ns._default - ns.add_prefixmap('semweb_context') - ns.add_prefixmap('monarch_context') - self.assertEqual('https://monarchinitiative.org/', str(ns._default)) + ns.add_prefixmap("semweb_context") + ns.add_prefixmap("monarch_context") + self.assertEqual("https://monarchinitiative.org/", str(ns._default)) del ns._default - ns._default = ns['meta'] - self.assertEqual('l1:foo', ns.curie_for("http://example.org/subset/foo")) - self.assertEqual('l2:foo', ns.curie_for("http://example.org/subset/test/foo")) - self.assertEqual('l3:able/foo', ns.curie_for("http://example.org/subset/table/foo")) - self.assertEqual('u1:foo', ns.curie_for("urn:example:foo")) + ns._default = ns["meta"] + self.assertEqual("l1:foo", ns.curie_for("http://example.org/subset/foo")) + self.assertEqual("l2:foo", ns.curie_for("http://example.org/subset/test/foo")) + self.assertEqual("l3:able/foo", ns.curie_for("http://example.org/subset/table/foo")) + self.assertEqual("u1:foo", ns.curie_for("urn:example:foo")) with self.assertRaises(ValueError): ns.curie_for("1abc\junk") # no comment in skos? # self.assertEqual(SKOS.comment, ns.uri_for("skos:comment")) - self.assertEqual(URIRef('http://example.org/dc/table'), ns.uri_for("dc:table")) + self.assertEqual(URIRef("http://example.org/dc/table"), ns.uri_for("dc:table")) self.assertEqual(ns.uri_for("http://something.org"), URIRef("http://something.org")) - self.assertEqual('https://w3id.org/biolink/metamodel/Schema', str(ns.uri_for(":Schema"))) - self.assertEqual(URIRef('http://example.org/wrong/Base'), ns.uri_for("Base")) + self.assertEqual("https://w3id.org/biolink/metamodel/Schema", str(ns.uri_for(":Schema"))) + self.assertEqual(URIRef("http://example.org/wrong/Base"), ns.uri_for("Base")) del ns._base with self.assertRaises(ValueError): ns.uri_for("Base") try: ns.uri_for("Base") except ValueError as e: - self.assertEqual('Unknown CURIE prefix: @base', str(e)) + self.assertEqual("Unknown CURIE prefix: @base", str(e)) self.assertIsNone(ns.curie_for("http://google.com/test")) with self.assertRaises(ValueError): @@ -84,37 +84,37 @@ def test_namespaces(self): def test_prefixmaps_integration(self): prefixmap_merged = Namespaces() - prefixmap_merged.add_prefixmap('merged') + prefixmap_merged.add_prefixmap("merged") self.assertGreater(len(prefixmap_merged), 3780) - prefixmap_merged.add_prefixmap('monarch_context') + prefixmap_merged.add_prefixmap("monarch_context") self.assertGreater(len(prefixmap_merged), 3850) - self.assertRaises(ValueError, prefixmap_merged.add_prefixmap, 'nonexistent_context') + self.assertRaises(ValueError, prefixmap_merged.add_prefixmap, "nonexistent_context") - prefixmap_merged.add_prefixmap('bioregistry') + prefixmap_merged.add_prefixmap("bioregistry") self.assertGreater(len(prefixmap_merged), 3860) - test_NCIT_curie = 'NCIT:C25300' - test_NCIT_uri = URIRef('http://purl.obolibrary.org/obo/NCIT_C25300') + test_NCIT_curie = "NCIT:C25300" + test_NCIT_uri = URIRef("http://purl.obolibrary.org/obo/NCIT_C25300") self.assertEqual(prefixmap_merged.curie_for(test_NCIT_uri), test_NCIT_curie) self.assertEqual(prefixmap_merged.uri_for(test_NCIT_curie), test_NCIT_uri) def test_prefix_suffix(self): ns = Namespaces() - ns['farm'] = 'https://example.org/farm' - ns['farm_slash'] = 'https://slash.org/farm/' + ns["farm"] = "https://example.org/farm" + ns["farm_slash"] = "https://slash.org/farm/" - self.assertEqual(('farm', 'cow'), ns.prefix_suffix('farm:cow')) - self.assertEqual(('farm', '/cow'), ns.prefix_suffix('https://example.org/farm/cow')) - self.assertEqual(('farm_slash', 'cow'), ns.prefix_suffix('https://slash.org/farm/cow')) - self.assertEqual(('farm_slash', 'cow/horns'), ns.prefix_suffix('farm_slash:cow/horns')) - self.assertEqual(('farm', '/cow/horns'), ns.prefix_suffix('farm:/cow/horns')) - self.assertEqual(('farm', '#cow/horns'), ns.prefix_suffix('farm:#cow/horns')) - self.assertEqual(('farm', ''), ns.prefix_suffix('farm:')) - self.assertEqual(('', 'cow'), ns.prefix_suffix(':cow')) - self.assertEqual((None, None), ns.prefix_suffix('https://missing-prefix.org/farm/cow')) + self.assertEqual(("farm", "cow"), ns.prefix_suffix("farm:cow")) + self.assertEqual(("farm", "/cow"), ns.prefix_suffix("https://example.org/farm/cow")) + self.assertEqual(("farm_slash", "cow"), ns.prefix_suffix("https://slash.org/farm/cow")) + self.assertEqual(("farm_slash", "cow/horns"), ns.prefix_suffix("farm_slash:cow/horns")) + self.assertEqual(("farm", "/cow/horns"), ns.prefix_suffix("farm:/cow/horns")) + self.assertEqual(("farm", "#cow/horns"), ns.prefix_suffix("farm:#cow/horns")) + self.assertEqual(("farm", ""), ns.prefix_suffix("farm:")) + self.assertEqual(("", "cow"), ns.prefix_suffix(":cow")) + self.assertEqual((None, None), ns.prefix_suffix("https://missing-prefix.org/farm/cow")) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_pattern.py b/tests/test_utils/test_pattern.py index 81df8c01..c61464fa 100644 --- a/tests/test_utils/test_pattern.py +++ b/tests/test_utils/test_pattern.py @@ -1,10 +1,8 @@ import unittest -from tests.test_utils.environment import env - -from linkml_runtime.utils.schemaview import SchemaView - from linkml_runtime.utils.pattern import PatternResolver, generate_patterns +from linkml_runtime.utils.schemaview import SchemaView +from tests.test_utils.environment import env class PatternTestCase(unittest.TestCase): @@ -22,7 +20,6 @@ def test_generate_patterns(self): self.assertDictEqual(actual_dict, expected_dict) - def test_pattern_resolver(self): sv = SchemaView(env.input_path("pattern-example.yaml")) diff --git a/tests/test_utils/test_poly_dataclasses.py b/tests/test_utils/test_poly_dataclasses.py index 9f381075..ad6f4340 100644 --- a/tests/test_utils/test_poly_dataclasses.py +++ b/tests/test_utils/test_poly_dataclasses.py @@ -1,31 +1,33 @@ import unittest -from linkml_runtime.linkml_model.meta import Element, LINKML + +from linkml_runtime.linkml_model.meta import LINKML, Element + class PolyDataclassTestCase(unittest.TestCase): def test_class_for_uri(self): - """ Test various class lookup options """ + """Test various class lookup options""" e = Element # Test class URI cls = e._class_for_uri(LINKML.ClassDefinition) - self.assertEqual('ClassDefinition', cls.__name__) + self.assertEqual("ClassDefinition", cls.__name__) # Test model URI cls = e._class_for_uri(LINKML.TypeDefinition, use_model_uri=True) - self.assertEqual('TypeDefinition', cls.__name__) + self.assertEqual("TypeDefinition", cls.__name__) # Test class curie (note there isn't any model curie cls = e._class_for_curie("linkml:TypeDefinition") - self.assertEqual('TypeDefinition', cls.__name__) + self.assertEqual("TypeDefinition", cls.__name__) # Make sure the self test works cls = e._class_for_uri(LINKML.Element) - self.assertEqual('Element', cls.__name__) + self.assertEqual("Element", cls.__name__) # Make sure we fail gracefully cls = e._class_for_uri("linkml:Missing") self.assertIsNone(cls) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_ruleutils.py b/tests/test_utils/test_ruleutils.py index c1975985..317ec82b 100644 --- a/tests/test_utils/test_ruleutils.py +++ b/tests/test_utils/test_ruleutils.py @@ -3,12 +3,11 @@ from linkml_runtime.dumpers import yaml_dumper from linkml_runtime.loaders.yaml_loader import YAMLLoader +from linkml_runtime.utils.ruleutils import get_range_as_disjunction, subclass_to_rules from linkml_runtime.utils.schemaview import SchemaView -from linkml_runtime.utils.ruleutils import subclass_to_rules, get_range_as_disjunction - from tests.test_utils import INPUT_DIR -SCHEMA = os.path.join(INPUT_DIR, 'rules-example.yaml') +SCHEMA = os.path.join(INPUT_DIR, "rules-example.yaml") yaml_loader = YAMLLoader() @@ -18,28 +17,26 @@ class RuleUtilsTestCase(unittest.TestCase): def test_disjunction(self): # no import schema view = SchemaView(SCHEMA) - analyte = view.induced_slot('analyte', 'Sample') - #print(analyte) - #print(analyte.any_of) + analyte = view.induced_slot("analyte", "Sample") + # print(analyte) + # print(analyte.any_of) disj = get_range_as_disjunction(analyte) - #print(disj) - self.assertCountEqual(disj, {'MissingValueEnum', 'AnalyteEnum'}) + # print(disj) + self.assertCountEqual(disj, {"MissingValueEnum", "AnalyteEnum"}) for s in view.all_slots().values(): disj = get_range_as_disjunction(s) - print(f'{s.name} DISJ: {disj}') + print(f"{s.name} DISJ: {disj}") def test_roll_up(self): # no import schema view = SchemaView(SCHEMA) - c = view.get_class('ProteinCodingGene') - rules = subclass_to_rules(view, 'ProteinCodingGene', 'SeqFeature') + c = view.get_class("ProteinCodingGene") + rules = subclass_to_rules(view, "ProteinCodingGene", "SeqFeature") rule = rules[0] - print(f'IF: {rule.preconditions}') - print(f'THEN: {rule.postconditions}') + print(f"IF: {rule.preconditions}") + print(f"THEN: {rule.postconditions}") print(yaml_dumper.dumps(rule)) - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_schema_as_dict.py b/tests/test_utils/test_schema_as_dict.py index 90ec7042..549aeedb 100644 --- a/tests/test_utils/test_schema_as_dict.py +++ b/tests/test_utils/test_schema_as_dict.py @@ -1,20 +1,19 @@ +import logging import os import unittest -import logging from linkml_runtime.linkml_model.meta import ClassDefinition from linkml_runtime.loaders.yaml_loader import YAMLLoader -from linkml_runtime.utils.schema_as_dict import schema_as_yaml_dump, schema_as_dict +from linkml_runtime.utils.schema_as_dict import schema_as_dict, schema_as_yaml_dump +from linkml_runtime.utils.schema_builder import SchemaBuilder, SlotDefinition from linkml_runtime.utils.schemaview import SchemaView -from linkml_runtime.utils.schema_builder import ClassDefinition, SchemaBuilder, SlotDefinition - from tests.test_utils import INPUT_DIR, OUTPUT_DIR logger = logging.getLogger(__name__) -SCHEMA_NO_IMPORTS = os.path.join(INPUT_DIR, 'kitchen_sink_noimports.yaml') -SCHEMA_WITH_IMPORTS = os.path.join(INPUT_DIR, 'kitchen_sink.yaml') -CLEAN_SCHEMA = os.path.join(OUTPUT_DIR, 'kitchen_sink.clean.yaml') +SCHEMA_NO_IMPORTS = os.path.join(INPUT_DIR, "kitchen_sink_noimports.yaml") +SCHEMA_WITH_IMPORTS = os.path.join(INPUT_DIR, "kitchen_sink.yaml") +CLEAN_SCHEMA = os.path.join(OUTPUT_DIR, "kitchen_sink.clean.yaml") yaml_loader = YAMLLoader() @@ -27,26 +26,25 @@ def test_as_dict(self): """ view = SchemaView(SCHEMA_NO_IMPORTS) all_slots = view.all_slots() - self.assertIn('name', all_slots) + self.assertIn("name", all_slots) logger.debug(view.schema.id) ystr = schema_as_yaml_dump(view.schema) - with open(CLEAN_SCHEMA, 'w') as stream: + with open(CLEAN_SCHEMA, "w") as stream: stream.write(ystr) view2 = SchemaView(ystr) obj = schema_as_dict(view.schema) # ensure that prefixes are compacted - assert obj['prefixes']['pav'] == 'http://purl.org/pav/' - assert '@type' not in obj - for k in ['slots', 'classes', 'enums', 'subsets']: + assert obj["prefixes"]["pav"] == "http://purl.org/pav/" + assert "@type" not in obj + for k in ["slots", "classes", "enums", "subsets"]: elt_dict = obj[k] for e_name, e in elt_dict.items(): - assert 'name' not in e - if k == 'enums': + assert "name" not in e + if k == "enums": for e in elt_dict.values(): - for pv in e.get('permissible_values', {}).values(): - assert 'text' not in pv - self.assertIn('name', obj['slots']) - + for pv in e.get("permissible_values", {}).values(): + assert "text" not in pv + self.assertIn("name", obj["slots"]) def test_as_dict_with_attributes(self): """ @@ -64,14 +62,14 @@ def test_as_dict_with_attributes(self): # Verify that the 'name' slot exists in the schema view = SchemaView(builder.schema) - self.assertIn('name', view.all_slots()) + self.assertIn("name", view.all_slots()) # Convert the schema to a dict obj = schema_as_dict(view.schema) # Verify that the 'name' slot still exists, as an attribute - self.assertIn('name', obj['classes']['Patient']['attributes']) + self.assertIn("name", obj["classes"]["Patient"]["attributes"]) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_schema_builder.py b/tests/test_utils/test_schema_builder.py index 5ebc66a9..3a0b9332 100644 --- a/tests/test_utils/test_schema_builder.py +++ b/tests/test_utils/test_schema_builder.py @@ -1,15 +1,15 @@ -from typing import Optional, Union, Any from dataclasses import fields +from typing import Any, Optional, Union import pytest -from linkml_runtime.utils.schema_builder import SchemaBuilder from linkml_runtime.linkml_model import ( ClassDefinition, - SlotDefinition, EnumDefinition, PermissibleValue, + SlotDefinition, ) +from linkml_runtime.utils.schema_builder import SchemaBuilder # === Tests for `SchemaBuilder.add_class` === @@ -49,9 +49,7 @@ def test_add_existing_class(replace_if_present): ], ) @pytest.mark.parametrize("use_attributes", [True, False]) -def test_add_class_with_slot_additions( - slots: Optional[list[Union[str, SlotDefinition]]], use_attributes: bool -): +def test_add_class_with_slot_additions(slots: Optional[list[Union[str, SlotDefinition]]], use_attributes: bool): """ Test adding a class with separate additional slots specification """ @@ -263,4 +261,5 @@ def test_add_enum_with_extra_kwargs( assert added_enum == expected_added_enum -# === Tests for `SchemaBuilder.add_enum` end === \ No newline at end of file + +# === Tests for `SchemaBuilder.add_enum` end === diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py index 01ea81d6..91833402 100644 --- a/tests/test_utils/test_schemaview.py +++ b/tests/test_utils/test_schemaview.py @@ -1,38 +1,47 @@ -import os import logging +import os from copy import copy from pathlib import Path + import pytest from jsonasobj2 import JsonObj from linkml_runtime.dumpers import yaml_dumper -from linkml_runtime.linkml_model.meta import Example, SchemaDefinition, ClassDefinition, SlotDefinitionName, \ - SlotDefinition, \ - ClassDefinitionName, Prefix, TypeDefinition +from linkml_runtime.linkml_model.meta import ( + ClassDefinition, + ClassDefinitionName, + Example, + Prefix, + SchemaDefinition, + SlotDefinition, + SlotDefinitionName, + TypeDefinition, +) from linkml_runtime.loaders.yaml_loader import YAMLLoader from linkml_runtime.utils.introspection import package_schemaview -from linkml_runtime.utils.schemaview import SchemaView, SchemaUsage, OrderedBy -from linkml_runtime.utils.schemaops import roll_up, roll_down +from linkml_runtime.utils.schemaops import roll_down, roll_up +from linkml_runtime.utils.schemaview import SchemaUsage, SchemaView from tests.test_utils import INPUT_DIR logger = logging.getLogger(__name__) -SCHEMA_NO_IMPORTS = Path(INPUT_DIR) / 'kitchen_sink_noimports.yaml' -SCHEMA_WITH_IMPORTS = Path(INPUT_DIR) / 'kitchen_sink.yaml' -SCHEMA_WITH_STRUCTURED_PATTERNS = Path(INPUT_DIR) / 'pattern-example.yaml' -SCHEMA_IMPORT_TREE = Path(INPUT_DIR) / 'imports' / 'main.yaml' -SCHEMA_RELATIVE_IMPORT_TREE = Path(INPUT_DIR) / 'imports_relative' / 'L0_0' / 'L1_0_0' / 'main.yaml' -SCHEMA_RELATIVE_IMPORT_TREE2 = Path(INPUT_DIR) / 'imports_relative' / 'L0_2' / 'main.yaml' +SCHEMA_NO_IMPORTS = Path(INPUT_DIR) / "kitchen_sink_noimports.yaml" +SCHEMA_WITH_IMPORTS = Path(INPUT_DIR) / "kitchen_sink.yaml" +SCHEMA_WITH_STRUCTURED_PATTERNS = Path(INPUT_DIR) / "pattern-example.yaml" +SCHEMA_IMPORT_TREE = Path(INPUT_DIR) / "imports" / "main.yaml" +SCHEMA_RELATIVE_IMPORT_TREE = Path(INPUT_DIR) / "imports_relative" / "L0_0" / "L1_0_0" / "main.yaml" +SCHEMA_RELATIVE_IMPORT_TREE2 = Path(INPUT_DIR) / "imports_relative" / "L0_2" / "main.yaml" yaml_loader = YAMLLoader() -IS_CURRENT = 'is current' -EMPLOYED_AT = 'employed at' -COMPANY = 'Company' -AGENT = 'agent' -ACTIVITY = 'activity' -RELATED_TO = 'related to' -AGE_IN_YEARS = 'age in years' +IS_CURRENT = "is current" +EMPLOYED_AT = "employed at" +COMPANY = "Company" +AGENT = "agent" +ACTIVITY = "activity" +RELATED_TO = "related to" +AGE_IN_YEARS = "age in years" + @pytest.fixture def schema_view_no_imports(): @@ -48,7 +57,7 @@ def view(): def test_children_method(schema_view_no_imports): view = schema_view_no_imports children = view.get_children("Person") - assert children == ['Adult'] + assert children == ["Adult"] def test_all_aliases(schema_view_no_imports): @@ -63,6 +72,7 @@ def test_all_aliases(schema_view_no_imports): assert "B" in aliases["subset B"] assert "dad" in aliases["Adult"] + def test_alias_slot(schema_view_no_imports): """ Tests the alias slot. @@ -76,9 +86,9 @@ def test_alias_slot(schema_view_no_imports): for s in view.class_induced_slots(c.name): assert s.alias is not None # Assert that alias is not None - postal_code_slot = view.induced_slot('postal code', 'Address') - assert postal_code_slot.name == 'postal code' # Assert name is 'postal code' - assert postal_code_slot.alias == 'zip' # Assert alias is 'zip' + postal_code_slot = view.induced_slot("postal code", "Address") + assert postal_code_slot.name == "postal code" # Assert name is 'postal code' + assert postal_code_slot.alias == "zip" # Assert alias is 'zip' def test_schemaview_enums(schema_view_no_imports): @@ -93,7 +103,7 @@ def test_schemaview_enums(schema_view_no_imports): for pv, v in e.permissible_values.items(): if pv == "CAT": assert view.permissible_value_parent(pv, e.name) is None - assert view.permissible_value_ancestors(pv, e.name) == ['CAT'] + assert view.permissible_value_ancestors(pv, e.name) == ["CAT"] assert "LION" in view.permissible_value_descendants(pv, e.name) assert "ANGRY_LION" in view.permissible_value_descendants(pv, e.name) assert "TABBY" in view.permissible_value_descendants(pv, e.name) @@ -105,13 +115,13 @@ def test_schemaview_enums(schema_view_no_imports): assert "ANGRY_LION" in view.permissible_value_children(pv, e.name) if pv == "ANGRY_LION": - assert view.permissible_value_parent(pv, e.name) == ['LION'] - assert view.permissible_value_ancestors(pv, e.name) == ['ANGRY_LION', 'LION', 'CAT'] + assert view.permissible_value_parent(pv, e.name) == ["LION"] + assert view.permissible_value_ancestors(pv, e.name) == ["ANGRY_LION", "LION", "CAT"] assert view.permissible_value_descendants(pv, e.name) == ["ANGRY_LION"] for cn, c in view.all_classes().items(): if c.name == "Adult": - assert view.class_ancestors(c.name) == ['Adult', 'Person', 'HasAliases', 'Thing'] + assert view.class_ancestors(c.name) == ["Adult", "Person", "HasAliases", "Thing"] def test_schemaview(schema_view_no_imports): @@ -120,13 +130,13 @@ def test_schemaview(schema_view_no_imports): assert len(view.imports_closure()) == 1 all_cls = view.all_classes() - logger.debug(f'n_cls = {len(all_cls)}') + logger.debug(f"n_cls = {len(all_cls)}") - assert list(view.annotation_dict(IS_CURRENT).values()) == ['bar'] + assert list(view.annotation_dict(IS_CURRENT).values()) == ["bar"] logger.debug(view.annotation_dict(EMPLOYED_AT)) e = view.get_element(EMPLOYED_AT) logger.debug(e.annotations) - e = view.get_element('has employment history') + e = view.get_element("has employment history") logger.debug(e.annotations) elements = view.get_elements_applicable_by_identifier("ORCID:1234") @@ -138,18 +148,18 @@ def test_schemaview(schema_view_no_imports): elements = view.get_elements_applicable_by_identifier("TEST:1234") assert "anatomical entity" not in elements - assert list(view.annotation_dict(SlotDefinitionName(IS_CURRENT)).values()) == ['bar'] + assert list(view.annotation_dict(SlotDefinitionName(IS_CURRENT)).values()) == ["bar"] logger.debug(view.annotation_dict(SlotDefinitionName(EMPLOYED_AT))) element = view.get_element(SlotDefinitionName(EMPLOYED_AT)) logger.debug(element.annotations) - element = view.get_element(SlotDefinitionName('has employment history')) + element = view.get_element(SlotDefinitionName("has employment history")) logger.debug(element.annotations) - assert view.is_mixin('WithLocation') - assert not view.is_mixin('BirthEvent') + assert view.is_mixin("WithLocation") + assert not view.is_mixin("BirthEvent") - assert view.inverse('employment history of') == 'has employment history' - assert view.inverse('has employment history') == 'employment history of' + assert view.inverse("employment history of") == "has employment history" + assert view.inverse("has employment history") == "employment history of" mapping = view.get_mapping_index() assert mapping is not None @@ -157,223 +167,241 @@ def test_schemaview(schema_view_no_imports): category_mapping = view.get_element_by_mapping("GO:0005198") assert category_mapping == [ACTIVITY] - assert view.is_multivalued("aliases") assert not view.is_multivalued("id") assert view.is_multivalued("dog addresses") - assert view.slot_is_true_for_metadata_property('aliases', 'multivalued') - assert view.slot_is_true_for_metadata_property('id', 'identifier') + assert view.slot_is_true_for_metadata_property("aliases", "multivalued") + assert view.slot_is_true_for_metadata_property("id", "identifier") with pytest.raises(ValueError): - view.slot_is_true_for_metadata_property('aliases', 'aliases') + view.slot_is_true_for_metadata_property("aliases", "aliases") for tn, t in view.all_types().items(): - logger.info(f'TN = {tn}') - assert t.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' + logger.info(f"TN = {tn}") + assert t.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" for sn, s in view.all_slots().items(): - logger.info(f'SN = {sn} RANGE={s.range}') - assert s.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' + logger.info(f"SN = {sn} RANGE={s.range}") + assert s.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" rng = view.induced_slot(sn).range assert rng is not None for cn in all_cls.keys(): c = view.get_class(cn) - assert c.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' - logger.debug(f'{cn} PARENTS = {view.class_parents(cn)}') - logger.debug(f'{cn} ANCS = {view.class_ancestors(cn)}') - logger.debug(f'{cn} CHILDREN = {view.class_children(cn)}') - logger.debug(f'{cn} DESCS = {view.class_descendants(cn)}') - logger.debug(f'{cn} SCHEMA = {view.in_schema(cn)}') - logger.debug(f' SLOTS = {view.class_slots(cn)}') + assert c.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" + logger.debug(f"{cn} PARENTS = {view.class_parents(cn)}") + logger.debug(f"{cn} ANCS = {view.class_ancestors(cn)}") + logger.debug(f"{cn} CHILDREN = {view.class_children(cn)}") + logger.debug(f"{cn} DESCS = {view.class_descendants(cn)}") + logger.debug(f"{cn} SCHEMA = {view.in_schema(cn)}") + logger.debug(f" SLOTS = {view.class_slots(cn)}") for sn in view.class_slots(cn): slot = view.get_slot(sn) - assert slot.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' - logger.debug(f' SLOT {sn} R: {slot.range} U: {view.get_uri(sn)} ANCS: {view.slot_ancestors(sn)}') + assert slot.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" + logger.debug(f" SLOT {sn} R: {slot.range} U: {view.get_uri(sn)} ANCS: {view.slot_ancestors(sn)}") induced_slot = view.induced_slot(sn, cn) - logger.debug(f' INDUCED {sn}={induced_slot}') + logger.debug(f" INDUCED {sn}={induced_slot}") assert induced_slot.range is not None - logger.debug(f'ALL = {view.all_elements().keys()}') + logger.debug(f"ALL = {view.all_elements().keys()}") # -- TEST ANCESTOR/DESCENDANTS FUNCTIONS -- - assert set(view.class_ancestors(COMPANY)) == {'Company', 'Organization', 'HasAliases', 'Thing'} - assert set(view.class_ancestors(COMPANY, reflexive=False)) == {'Organization', 'HasAliases', 'Thing'} - assert set(view.class_descendants('Thing')) == {'Thing', 'Person', 'Organization', COMPANY, 'Adult'} + assert set(view.class_ancestors(COMPANY)) == {"Company", "Organization", "HasAliases", "Thing"} + assert set(view.class_ancestors(COMPANY, reflexive=False)) == {"Organization", "HasAliases", "Thing"} + assert set(view.class_descendants("Thing")) == {"Thing", "Person", "Organization", COMPANY, "Adult"} # -- TEST CLASS SLOTS -- - assert set(view.class_slots('Person')) == { - 'id', 'name', 'has employment history', 'has familial relationships', - 'has medical history', AGE_IN_YEARS, 'addresses', 'has birth event', - 'reason_for_happiness', 'aliases' - } - assert view.class_slots('Person') == view.class_slots('Adult') - assert set(view.class_slots(COMPANY)) == { - 'id', 'name', 'ceo', 'aliases' + assert set(view.class_slots("Person")) == { + "id", + "name", + "has employment history", + "has familial relationships", + "has medical history", + AGE_IN_YEARS, + "addresses", + "has birth event", + "reason_for_happiness", + "aliases", } + assert view.class_slots("Person") == view.class_slots("Adult") + assert set(view.class_slots(COMPANY)) == {"id", "name", "ceo", "aliases"} - assert view.get_class(AGENT).class_uri == 'prov:Agent' - assert view.get_uri(AGENT) == 'prov:Agent' + assert view.get_class(AGENT).class_uri == "prov:Agent" + assert view.get_uri(AGENT) == "prov:Agent" logger.debug(view.get_class(COMPANY).class_uri) - assert view.get_uri(COMPANY) == 'ks:Company' + assert view.get_uri(COMPANY) == "ks:Company" # test induced slots - for c in [COMPANY, 'Person', 'Organization']: - islot = view.induced_slot('aliases', c) + for c in [COMPANY, "Person", "Organization"]: + islot = view.induced_slot("aliases", c) assert islot.multivalued is True assert islot.owner == c - assert view.get_uri(islot, expand=True) == 'https://w3id.org/linkml/tests/kitchen_sink/aliases' - - assert view.get_identifier_slot('Company').name == 'id' - assert view.get_identifier_slot('Thing').name == 'id' - assert view.get_identifier_slot('FamilialRelationship') is None - - for c in [COMPANY, 'Person', 'Organization', 'Thing']: - assert view.induced_slot('id', c).identifier - assert not view.induced_slot('name', c).identifier - assert not view.induced_slot('name', c).required - assert view.induced_slot('name', c).range == 'string' - assert view.induced_slot('id', c).owner == c - assert view.induced_slot('name', c).owner == c - - for c in ['Event', 'EmploymentEvent', 'MedicalEvent']: - s = view.induced_slot('started at time', c) - logger.debug(f's={s.range} // c = {c}') - assert s.range == 'date' - assert s.slot_uri == 'prov:startedAtTime' + assert view.get_uri(islot, expand=True) == "https://w3id.org/linkml/tests/kitchen_sink/aliases" + + assert view.get_identifier_slot("Company").name == "id" + assert view.get_identifier_slot("Thing").name == "id" + assert view.get_identifier_slot("FamilialRelationship") is None + + for c in [COMPANY, "Person", "Organization", "Thing"]: + assert view.induced_slot("id", c).identifier + assert not view.induced_slot("name", c).identifier + assert not view.induced_slot("name", c).required + assert view.induced_slot("name", c).range == "string" + assert view.induced_slot("id", c).owner == c + assert view.induced_slot("name", c).owner == c + + for c in ["Event", "EmploymentEvent", "MedicalEvent"]: + s = view.induced_slot("started at time", c) + logger.debug(f"s={s.range} // c = {c}") + assert s.range == "date" + assert s.slot_uri == "prov:startedAtTime" assert s.owner == c c_induced = view.induced_class(c) assert c_induced.slots == [] assert c_induced.attributes != [] - s2 = c_induced.attributes['started at time'] - assert s2.range == 'date' - assert s2.slot_uri == 'prov:startedAtTime' + s2 = c_induced.attributes["started at time"] + assert s2.range == "date" + assert s2.slot_uri == "prov:startedAtTime" # test slot_usage - assert view.induced_slot(AGE_IN_YEARS, 'Person').minimum_value == 0 - assert view.induced_slot(AGE_IN_YEARS, 'Adult').minimum_value == 16 - assert view.induced_slot('name', 'Person').pattern is not None - assert view.induced_slot('type', 'FamilialRelationship').range == 'FamilialRelationshipType' - assert view.induced_slot(RELATED_TO, 'FamilialRelationship').range == 'Person' - assert view.get_slot(RELATED_TO).range == 'Thing' - assert view.induced_slot(RELATED_TO, 'Relationship').range == 'Thing' - assert set(view.induced_slot('name').domain_of) == {'Thing', 'Place'} + assert view.induced_slot(AGE_IN_YEARS, "Person").minimum_value == 0 + assert view.induced_slot(AGE_IN_YEARS, "Adult").minimum_value == 16 + assert view.induced_slot("name", "Person").pattern is not None + assert view.induced_slot("type", "FamilialRelationship").range == "FamilialRelationshipType" + assert view.induced_slot(RELATED_TO, "FamilialRelationship").range == "Person" + assert view.get_slot(RELATED_TO).range == "Thing" + assert view.induced_slot(RELATED_TO, "Relationship").range == "Thing" + assert set(view.induced_slot("name").domain_of) == {"Thing", "Place"} a = view.get_class(ACTIVITY) - assert set(a.exact_mappings) == {'prov:Activity'} + assert set(a.exact_mappings) == {"prov:Activity"} logger.debug(view.get_mappings(ACTIVITY, expand=True)) - assert set(view.get_mappings(ACTIVITY)['exact']) == {'prov:Activity'} - assert set(view.get_mappings(ACTIVITY, expand=True)['exact']) == {'http://www.w3.org/ns/prov#Activity'} + assert set(view.get_mappings(ACTIVITY)["exact"]) == {"prov:Activity"} + assert set(view.get_mappings(ACTIVITY, expand=True)["exact"]) == {"http://www.w3.org/ns/prov#Activity"} u = view.usage_index() for k, v in u.items(): - logger.debug(f' {k} = {v}') - - assert SchemaUsage(used_by='FamilialRelationship', slot=RELATED_TO, - metaslot='range', used='Person', inferred=False) in u['Person'] - assert [SchemaUsage(used_by='Person', - slot='reason_for_happiness', - metaslot='any_of[range]', - used='MarriageEvent', - inferred=True - ), - SchemaUsage(used_by='Adult', - slot='reason_for_happiness', - metaslot='any_of[range]', - used='MarriageEvent', - inferred=False - )] == u['MarriageEvent'] - assert [SchemaUsage(used_by='Person', - slot='has employment history', - metaslot='range', - used='EmploymentEvent', - inferred=True), - SchemaUsage(used_by='Person', - slot='reason_for_happiness', - metaslot='any_of[range]', - used='EmploymentEvent', - inferred=True), - SchemaUsage(used_by='Adult', - slot='has employment history', - metaslot='range', - used='EmploymentEvent', - inferred=False), - SchemaUsage(used_by='Adult', - slot='reason_for_happiness', - metaslot='any_of[range]', - used='EmploymentEvent', - inferred=False)] == u['EmploymentEvent'] + logger.debug(f" {k} = {v}") + + assert ( + SchemaUsage( + used_by="FamilialRelationship", slot=RELATED_TO, metaslot="range", used="Person", inferred=False + ) + in u["Person"] + ) + assert [ + SchemaUsage( + used_by="Person", + slot="reason_for_happiness", + metaslot="any_of[range]", + used="MarriageEvent", + inferred=True, + ), + SchemaUsage( + used_by="Adult", + slot="reason_for_happiness", + metaslot="any_of[range]", + used="MarriageEvent", + inferred=False, + ), + ] == u["MarriageEvent"] + assert [ + SchemaUsage( + used_by="Person", slot="has employment history", metaslot="range", used="EmploymentEvent", inferred=True + ), + SchemaUsage( + used_by="Person", + slot="reason_for_happiness", + metaslot="any_of[range]", + used="EmploymentEvent", + inferred=True, + ), + SchemaUsage( + used_by="Adult", slot="has employment history", metaslot="range", used="EmploymentEvent", inferred=False + ), + SchemaUsage( + used_by="Adult", + slot="reason_for_happiness", + metaslot="any_of[range]", + used="EmploymentEvent", + inferred=False, + ), + ] == u["EmploymentEvent"] # test methods also work for attributes leaves = view.class_leaves() - logger.debug(f'LEAVES={leaves}') - assert 'MedicalEvent' in leaves + logger.debug(f"LEAVES={leaves}") + assert "MedicalEvent" in leaves roots = view.class_roots() - logger.debug(f'ROOTS={roots}') - assert 'Dataset' in roots - ds_slots = view.class_slots('Dataset') + logger.debug(f"ROOTS={roots}") + assert "Dataset" in roots + ds_slots = view.class_slots("Dataset") logger.debug(ds_slots) assert len(ds_slots) == 3 - assert len(['persons', 'companies', 'activities']) == len(ds_slots) + assert len(["persons", "companies", "activities"]) == len(ds_slots) for sn in ds_slots: - s = view.induced_slot(sn, 'Dataset') + s = view.induced_slot(sn, "Dataset") logger.debug(s) + def test_rollup_rolldown(schema_view_no_imports): # no import schema view = schema_view_no_imports - element_name = 'Event' + element_name = "Event" roll_up(view, element_name) for slot in view.class_induced_slots(element_name): logger.debug(slot) induced_slot_names = [s.name for s in view.class_induced_slots(element_name)] logger.debug(induced_slot_names) - assert len(['started at time', 'ended at time', IS_CURRENT, 'in location', EMPLOYED_AT, 'married to']) == len(induced_slot_names) + assert len(["started at time", "ended at time", IS_CURRENT, "in location", EMPLOYED_AT, "married to"]) == len( + induced_slot_names + ) # check to make sure rolled-up classes are deleted assert view.class_descendants(element_name, reflexive=False) == [] roll_down(view, view.class_leaves()) for element_name in view.all_classes(): - logger.debug(f'{element_name}') - logger.debug(f' {element_name} SLOTS(i) = {view.class_slots(element_name)}') - logger.debug(f' {element_name} SLOTS(d) = {view.class_slots(element_name, direct=True)}') + logger.debug(f"{element_name}") + logger.debug(f" {element_name} SLOTS(i) = {view.class_slots(element_name)}") + logger.debug(f" {element_name} SLOTS(d) = {view.class_slots(element_name, direct=True)}") assert len(view.class_slots(element_name)) == len(view.class_slots(element_name, direct=True)) - assert 'Thing' not in view.all_classes() - assert 'Person' not in view.all_classes() - assert 'Adult' in view.all_classes() + assert "Thing" not in view.all_classes() + assert "Person" not in view.all_classes() + assert "Adult" in view.all_classes() + def test_caching(): """ Determine if cache is reset after modifications made to schema """ - schema = SchemaDefinition(id='test', name='test') + schema = SchemaDefinition(id="test", name="test") view = SchemaView(schema) assert len([]) == len(view.all_classes()) - view.add_class(ClassDefinition('X')) - assert len(['X']) == len(view.all_classes()) - view.add_class(ClassDefinition('Y')) - assert len(['X', 'Y']) == len(view.all_classes()) + view.add_class(ClassDefinition("X")) + assert len(["X"]) == len(view.all_classes()) + view.add_class(ClassDefinition("Y")) + assert len(["X", "Y"]) == len(view.all_classes()) # bypass view method and add directly to schema; # in general this is not recommended as the cache will # not be updated - view.schema.classes['Z'] = ClassDefinition('Z') + view.schema.classes["Z"] = ClassDefinition("Z") # as expected, the view doesn't know about Z - assert len(['X', 'Y']) == len(view.all_classes()) + assert len(["X", "Y"]) == len(view.all_classes()) # inform the view modifications have been made view.set_modified() # should be in sync - assert len(['X', 'Y', 'Z']) == len(view.all_classes()) + assert len(["X", "Y", "Z"]) == len(view.all_classes()) # recommended way to make updates - view.delete_class('X') + view.delete_class("X") # cache will be up to date - assert len(['Y', 'Z']) == len(view.all_classes()) - view.add_class(ClassDefinition('W')) - assert len(['Y', 'Z', 'W']) == len(view.all_classes()) + assert len(["Y", "Z"]) == len(view.all_classes()) + view.add_class(ClassDefinition("W")) + assert len(["Y", "Z", "W"]) == len(view.all_classes()) def test_import_map(): @@ -388,30 +416,32 @@ def test_import_map(): for im in [None, {}, {"core": "core"}]: view = SchemaView(SCHEMA_WITH_IMPORTS, importmap=im) view.all_classes() - assert view.imports_closure().sort() == ['kitchen_sink', 'core', 'linkml:types'].sort() # Assert imports closure + assert ( + view.imports_closure().sort() == ["kitchen_sink", "core", "linkml:types"].sort() + ) # Assert imports closure assert ACTIVITY in view.all_classes() # Assert ACTIVITY is in all classes assert ACTIVITY not in view.all_classes(imports=False) # Assert ACTIVITY is not in classes without imports def test_imports(view): """view should by default dynamically include imports chain""" - assert (view.schema.source_file is not None) + assert view.schema.source_file is not None logger.debug(view.imports_closure()) - assert set(view.imports_closure()) == {'kitchen_sink', 'core', 'linkml:types'} + assert set(view.imports_closure()) == {"kitchen_sink", "core", "linkml:types"} for t in view.all_types().keys(): - logger.debug(f'T={t} in={view.in_schema(t)}') - assert view.in_schema(ClassDefinitionName('Person')) == 'kitchen_sink' - assert view.in_schema(SlotDefinitionName('id')) == 'core' - assert view.in_schema(SlotDefinitionName('name')) == 'core' - assert view.in_schema(SlotDefinitionName(ACTIVITY)) == 'core' - assert view.in_schema(SlotDefinitionName('string')) == 'types' + logger.debug(f"T={t} in={view.in_schema(t)}") + assert view.in_schema(ClassDefinitionName("Person")) == "kitchen_sink" + assert view.in_schema(SlotDefinitionName("id")) == "core" + assert view.in_schema(SlotDefinitionName("name")) == "core" + assert view.in_schema(SlotDefinitionName(ACTIVITY)) == "core" + assert view.in_schema(SlotDefinitionName("string")) == "types" assert ACTIVITY in view.all_classes() assert ACTIVITY not in view.all_classes(imports=False) - assert 'string' in view.all_types() - assert 'string' not in view.all_types(imports=False) - assert len(view.type_ancestors('SymbolString')) == len(['SymbolString', 'string']) + assert "string" in view.all_types() + assert "string" not in view.all_types(imports=False) + assert len(view.type_ancestors("SymbolString")) == len(["SymbolString", "string"]) for tn, t in view.all_types().items(): assert tn == t.name @@ -419,73 +449,76 @@ def test_imports(view): assert induced_t.uri is not None assert induced_t.base is not None if t in view.all_types(imports=False).values(): - assert t.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' + assert t.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" else: - assert t.from_schema in ['https://w3id.org/linkml/tests/core', 'https://w3id.org/linkml/types'] + assert t.from_schema in ["https://w3id.org/linkml/tests/core", "https://w3id.org/linkml/types"] for en, e in view.all_enums().items(): assert en == e.name if e in view.all_enums(imports=False).values(): - assert e.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' + assert e.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" else: - assert e.from_schema == 'https://w3id.org/linkml/tests/core' + assert e.from_schema == "https://w3id.org/linkml/tests/core" for sn, s in view.all_slots().items(): assert sn == s.name s_induced = view.induced_slot(sn) assert s_induced.range is not None if s in view.all_slots(imports=False).values(): - assert s.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' + assert s.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" else: - assert s.from_schema == 'https://w3id.org/linkml/tests/core' + assert s.from_schema == "https://w3id.org/linkml/tests/core" for cn, c in view.all_classes().items(): assert cn == c.name if c in view.all_classes(imports=False).values(): - assert c.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' + assert c.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" else: - assert c.from_schema == 'https://w3id.org/linkml/tests/core' + assert c.from_schema == "https://w3id.org/linkml/tests/core" for s in view.class_induced_slots(cn): if s in view.all_classes(imports=False).values(): assert s.slot_uri is not None - assert s.from_schema == 'https://w3id.org/linkml/tests/kitchen_sink' - - for c in ['Company', 'Person', 'Organization', 'Thing']: - assert view.induced_slot('id', c).identifier - assert not view.induced_slot('name', c).identifier - assert not view.induced_slot('name', c).required - assert view.induced_slot('name', c).range == 'string' - - for c in ['Event', 'EmploymentEvent', 'MedicalEvent']: - s = view.induced_slot('started at time', c) - assert s.range == 'date' - assert s.slot_uri == 'prov:startedAtTime' - - assert view.induced_slot(AGE_IN_YEARS, 'Person').minimum_value == 0 - assert view.induced_slot(AGE_IN_YEARS, 'Adult').minimum_value == 16 - - assert view.get_class('agent').class_uri == 'prov:Agent' - assert view.get_uri(AGENT) == 'prov:Agent' - logger.debug(view.get_class('Company').class_uri) - - assert view.get_uri(COMPANY) == 'ks:Company' - assert view.get_uri(COMPANY, expand=True) == 'https://w3id.org/linkml/tests/kitchen_sink/Company' - logger.debug(view.get_uri('TestClass')) - assert view.get_uri('TestClass') == 'core:TestClass' - assert view.get_uri('TestClass', expand=True) == 'https://w3id.org/linkml/tests/core/TestClass' - - assert view.get_uri('TestClass', expand=True, use_element_type=True) == 'https://w3id.org/linkml/tests/core/class/TestClass' - assert view.get_uri('TestClass', use_element_type=True) == 'core:class/TestClass' - assert view.get_uri('name', use_element_type=True) == 'core:slot/name' + assert s.from_schema == "https://w3id.org/linkml/tests/kitchen_sink" + + for c in ["Company", "Person", "Organization", "Thing"]: + assert view.induced_slot("id", c).identifier + assert not view.induced_slot("name", c).identifier + assert not view.induced_slot("name", c).required + assert view.induced_slot("name", c).range == "string" + + for c in ["Event", "EmploymentEvent", "MedicalEvent"]: + s = view.induced_slot("started at time", c) + assert s.range == "date" + assert s.slot_uri == "prov:startedAtTime" + + assert view.induced_slot(AGE_IN_YEARS, "Person").minimum_value == 0 + assert view.induced_slot(AGE_IN_YEARS, "Adult").minimum_value == 16 + + assert view.get_class("agent").class_uri == "prov:Agent" + assert view.get_uri(AGENT) == "prov:Agent" + logger.debug(view.get_class("Company").class_uri) + + assert view.get_uri(COMPANY) == "ks:Company" + assert view.get_uri(COMPANY, expand=True) == "https://w3id.org/linkml/tests/kitchen_sink/Company" + logger.debug(view.get_uri("TestClass")) + assert view.get_uri("TestClass") == "core:TestClass" + assert view.get_uri("TestClass", expand=True) == "https://w3id.org/linkml/tests/core/TestClass" + + assert ( + view.get_uri("TestClass", expand=True, use_element_type=True) + == "https://w3id.org/linkml/tests/core/class/TestClass" + ) + assert view.get_uri("TestClass", use_element_type=True) == "core:class/TestClass" + assert view.get_uri("name", use_element_type=True) == "core:slot/name" - assert view.get_uri('string') == 'xsd:string' + assert view.get_uri("string") == "xsd:string" # dynamic enums - e = view.get_enum('HCAExample') - assert set(e.include[0].reachable_from.source_nodes) == {'GO:0007049', 'GO:0022403'} + e = view.get_enum("HCAExample") + assert set(e.include[0].reachable_from.source_nodes) == {"GO:0007049", "GO:0022403"} # units - height = view.get_slot('height_in_m') + height = view.get_slot("height_in_m") assert height.unit.ucum_code == "m" @@ -501,14 +534,21 @@ def test_imports_closure_order(): sv = SchemaView(SCHEMA_IMPORT_TREE) closure = sv.imports_closure(imports=True) target = [ - 'linkml:types', - 's1_1', - 's1_2_1_1_1', 's1_2_1_1_2', - 's1_2_1_1', 's1_2_1', 's1_2', - 's1', - 's2_1', 's2_2', 's2', - 's3_1', 's3_2', 's3', - 'main' + "linkml:types", + "s1_1", + "s1_2_1_1_1", + "s1_2_1_1_2", + "s1_2_1_1", + "s1_2_1", + "s1_2", + "s1", + "s2_1", + "s2_2", + "s2", + "s3_1", + "s3_2", + "s3", + "main", ] assert closure == target @@ -520,7 +560,7 @@ def test_imports_overrides(): target = {} for name, cls in sv.all_classes(imports=True).items(): target[name] = name - defaults[name] = cls.attributes['value'].ifabsent + defaults[name] = cls.attributes["value"].ifabsent assert defaults == target @@ -532,33 +572,34 @@ def test_imports_relative(): assert len(closure) == len(sv.schema_map.keys()) assert closure == [ - 'linkml:types', - '../neighborhood_parent', - 'neighbor', - '../parent', - '../L1_0_1/L2_0_1_0/grandchild', - '../../L0_1/L1_1_0/L2_1_0_0/apple', - '../../L0_1/L1_1_0/L2_1_0_0/index', - '../../L0_1/L1_1_0/L2_1_0_1/banana', - '../../L0_1/L1_1_0/L2_1_0_1/index', - '../../L0_1/L1_1_0/index', - '../../L0_1/cousin', - '../L1_0_1/dupe', - './L2_0_0_0/child', - './L2_0_0_1/child', - 'L2_0_0_2/two', - 'L2_0_0_2/one', - 'L2_0_0_2/four', - 'L2_0_0_2/three', - 'L2_0_0_2/stepchild', - 'main' + "linkml:types", + "../neighborhood_parent", + "neighbor", + "../parent", + "../L1_0_1/L2_0_1_0/grandchild", + "../../L0_1/L1_1_0/L2_1_0_0/apple", + "../../L0_1/L1_1_0/L2_1_0_0/index", + "../../L0_1/L1_1_0/L2_1_0_1/banana", + "../../L0_1/L1_1_0/L2_1_0_1/index", + "../../L0_1/L1_1_0/index", + "../../L0_1/cousin", + "../L1_0_1/dupe", + "./L2_0_0_0/child", + "./L2_0_0_1/child", + "L2_0_0_2/two", + "L2_0_0_2/one", + "L2_0_0_2/four", + "L2_0_0_2/three", + "L2_0_0_2/stepchild", + "main", ] # check that we can actually get the classes from the same-named schema classes = sv.all_classes(imports=True) - assert 'L110Index' in classes - assert 'L2100Index' in classes - assert 'L2101Index' in classes + assert "L110Index" in classes + assert "L2100Index" in classes + assert "L2101Index" in classes + def test_imports_relative_load(): """Relative imports from relative imports should load without FileNotFoundError.""" @@ -590,6 +631,7 @@ def test_direct_remote_imports_additional(): class_count = len(view.all_classes()) assert class_count > 0 + def test_merge_imports(view): """ ensure merging and merging imports closure works @@ -603,6 +645,7 @@ def test_merge_imports(view): all_c2_noi = copy(view.all_classes(imports=False)) assert len(all_c2_noi) == len(all_c2) + def test_metamodel_imports(): """ Tests imports of the metamodel. @@ -611,7 +654,7 @@ def test_metamodel_imports(): SchemaView should make use of the version of the metamodel distributed with the package over the network available version. """ - schema = SchemaDefinition(id='test', name='metamodel-imports-test', imports=["linkml:meta"]) + schema = SchemaDefinition(id="test", name="metamodel-imports-test", imports=["linkml:meta"]) sv = SchemaView(schema) all_classes = sv.all_classes() assert len(all_classes) > 20 @@ -620,147 +663,135 @@ def test_metamodel_imports(): assert len(sv.all_classes()) > 20 assert all_classes == sv.all_classes() + def test_non_linkml_remote_import(): """ Test that a remote import _not_ using the linkml prefix works. See: https://github.com/linkml/linkml/issues/1627 """ schema = SchemaDefinition( - id='test_non_linkml_remote_import', - name='test_non_linkml_remote_import', - prefixes=[ - Prefix( - prefix_prefix="foo", - prefix_reference="https://w3id.org/linkml/" - ) - ], - imports=[ - "foo:types" - ], - slots=[ - SlotDefinition( - name="an_int", - range="integer" - ) - ], - classes=[ - ClassDefinition( - name="AClass", - slots=["an_int"] - ) - ] + id="test_non_linkml_remote_import", + name="test_non_linkml_remote_import", + prefixes=[Prefix(prefix_prefix="foo", prefix_reference="https://w3id.org/linkml/")], + imports=["foo:types"], + slots=[SlotDefinition(name="an_int", range="integer")], + classes=[ClassDefinition(name="AClass", slots=["an_int"])], ) sv = SchemaView(schema) slots = sv.class_induced_slots("AClass", imports=True) assert len(slots) == 1 + def test_traversal(): - schema = SchemaDefinition(id='test', name='traversal-test') + schema = SchemaDefinition(id="test", name="traversal-test") view = SchemaView(schema) - view.add_class(ClassDefinition('Root', mixins=['RootMixin'])) - view.add_class(ClassDefinition('A', is_a='Root', mixins=['Am1', 'Am2', 'AZ'])) - view.add_class(ClassDefinition('B', is_a='A', mixins=['Bm1', 'Bm2', 'BY'])) - view.add_class(ClassDefinition('C', is_a='B', mixins=['Cm1', 'Cm2', 'CX'])) - view.add_class(ClassDefinition('RootMixin', mixin=True)) - view.add_class(ClassDefinition('Am1', is_a='RootMixin', mixin=True)) - view.add_class(ClassDefinition('Am2', is_a='RootMixin', mixin=True)) - view.add_class(ClassDefinition('Bm1', is_a='Am1', mixin=True)) - view.add_class(ClassDefinition('Bm2', is_a='Am2', mixin=True)) - view.add_class(ClassDefinition('Cm1', is_a='Bm1', mixin=True)) - view.add_class(ClassDefinition('Cm2', is_a='Bm2', mixin=True)) - view.add_class(ClassDefinition('AZ', is_a='RootMixin', mixin=True)) - view.add_class(ClassDefinition('BY', is_a='RootMixin', mixin=True)) - view.add_class(ClassDefinition('CX', is_a='RootMixin', mixin=True)) + view.add_class(ClassDefinition("Root", mixins=["RootMixin"])) + view.add_class(ClassDefinition("A", is_a="Root", mixins=["Am1", "Am2", "AZ"])) + view.add_class(ClassDefinition("B", is_a="A", mixins=["Bm1", "Bm2", "BY"])) + view.add_class(ClassDefinition("C", is_a="B", mixins=["Cm1", "Cm2", "CX"])) + view.add_class(ClassDefinition("RootMixin", mixin=True)) + view.add_class(ClassDefinition("Am1", is_a="RootMixin", mixin=True)) + view.add_class(ClassDefinition("Am2", is_a="RootMixin", mixin=True)) + view.add_class(ClassDefinition("Bm1", is_a="Am1", mixin=True)) + view.add_class(ClassDefinition("Bm2", is_a="Am2", mixin=True)) + view.add_class(ClassDefinition("Cm1", is_a="Bm1", mixin=True)) + view.add_class(ClassDefinition("Cm2", is_a="Bm2", mixin=True)) + view.add_class(ClassDefinition("AZ", is_a="RootMixin", mixin=True)) + view.add_class(ClassDefinition("BY", is_a="RootMixin", mixin=True)) + view.add_class(ClassDefinition("CX", is_a="RootMixin", mixin=True)) def check(ancs, expected): assert ancs == expected - check(view.class_ancestors('C', depth_first=True), - ['C', 'Cm1', 'Cm2', 'CX', 'B', 'Bm1', 'Bm2', 'BY', 'A', 'Am1', 'Am2', 'AZ', 'Root', 'RootMixin']) - check(view.class_ancestors('C', depth_first=False), - ['C', 'Cm1', 'Cm2', 'CX', 'B', 'Bm1', 'Bm2', 'RootMixin', 'BY', 'A', 'Am1', 'Am2', 'AZ', 'Root']) - check(view.class_ancestors('C', mixins=False), - ['C', 'B', 'A', 'Root']) - check(view.class_ancestors('C', is_a=False), - ['C', 'Cm1', 'Cm2', 'CX']) + check( + view.class_ancestors("C", depth_first=True), + ["C", "Cm1", "Cm2", "CX", "B", "Bm1", "Bm2", "BY", "A", "Am1", "Am2", "AZ", "Root", "RootMixin"], + ) + check( + view.class_ancestors("C", depth_first=False), + ["C", "Cm1", "Cm2", "CX", "B", "Bm1", "Bm2", "RootMixin", "BY", "A", "Am1", "Am2", "AZ", "Root"], + ) + check(view.class_ancestors("C", mixins=False), ["C", "B", "A", "Root"]) + check(view.class_ancestors("C", is_a=False), ["C", "Cm1", "Cm2", "CX"]) + def test_slot_inheritance(): - schema = SchemaDefinition(id='test', name='test') + schema = SchemaDefinition(id="test", name="test") view = SchemaView(schema) - view.add_class(ClassDefinition('C', slots=['s1', 's2'])) - view.add_class(ClassDefinition('D')) - view.add_class(ClassDefinition('Z')) - view.add_class(ClassDefinition('W')) - - view.add_slot(SlotDefinition('s1', multivalued=True, range='D')) - view.add_slot(SlotDefinition('s2', is_a='s1')) - view.add_slot(SlotDefinition('s3', is_a='s2', mixins=['m1'])) - view.add_slot(SlotDefinition('s4', is_a='s2', mixins=['m1'], range='W')) - view.add_slot(SlotDefinition('m1', mixin=True, multivalued=False, range='Z')) - - slot1 = view.induced_slot('s1', 'C') + view.add_class(ClassDefinition("C", slots=["s1", "s2"])) + view.add_class(ClassDefinition("D")) + view.add_class(ClassDefinition("Z")) + view.add_class(ClassDefinition("W")) + + view.add_slot(SlotDefinition("s1", multivalued=True, range="D")) + view.add_slot(SlotDefinition("s2", is_a="s1")) + view.add_slot(SlotDefinition("s3", is_a="s2", mixins=["m1"])) + view.add_slot(SlotDefinition("s4", is_a="s2", mixins=["m1"], range="W")) + view.add_slot(SlotDefinition("m1", mixin=True, multivalued=False, range="Z")) + + slot1 = view.induced_slot("s1", "C") assert slot1.is_a is None - assert slot1.range == 'D' + assert slot1.range == "D" assert slot1.multivalued is not None - slot2 = view.induced_slot('s2', 'C') - assert slot2.is_a == 's1' - assert slot2.range == 'D' + slot2 = view.induced_slot("s2", "C") + assert slot2.is_a == "s1" + assert slot2.range == "D" assert slot2.multivalued is not None - slot3 = view.induced_slot('s3', 'C') + slot3 = view.induced_slot("s3", "C") assert slot3.multivalued is not None - assert slot3.range == 'Z' + assert slot3.range == "Z" - slot4 = view.induced_slot('s4', 'C') + slot4 = view.induced_slot("s4", "C") assert slot4.multivalued is not None - assert slot4.range == 'W' + assert slot4.range == "W" # Test dangling - view.add_slot(SlotDefinition('s5', is_a='does-not-exist')) + view.add_slot(SlotDefinition("s5", is_a="does-not-exist")) with pytest.raises(ValueError): - view.slot_ancestors('s5') + view.slot_ancestors("s5") def test_attribute_inheritance(): """ Tests attribute inheritance edge cases. """ - view = SchemaView(os.path.join(INPUT_DIR, 'attribute_edge_cases.yaml')) + view = SchemaView(os.path.join(INPUT_DIR, "attribute_edge_cases.yaml")) expected = [ - ('Root', 'a1', None, "a1"), - ('Root', 'a2', None, "a2"), - ('Root', 'a3', None, "a3"), - ('C1', 'a1', True, "a1m1"), - ('C1', 'a2', True, "a2c1"), - ('C1', 'a3', None, "a3"), - ('C1', 'a4', None, "a4"), - ('C2', 'a1', False, "a1m2"), - ('C2', 'a2', True, "a2c2"), - ('C2', 'a3', None, "a3"), - ('C2', 'a4', True, "a4m2"), - ('C1x', 'a1', True, "a1m1"), - ('C1x', 'a2', True, "a2c1x"), - ('C1x', 'a3', None, "a3"), - ('C1x', 'a4', None, "a4"), + ("Root", "a1", None, "a1"), + ("Root", "a2", None, "a2"), + ("Root", "a3", None, "a3"), + ("C1", "a1", True, "a1m1"), + ("C1", "a2", True, "a2c1"), + ("C1", "a3", None, "a3"), + ("C1", "a4", None, "a4"), + ("C2", "a1", False, "a1m2"), + ("C2", "a2", True, "a2c2"), + ("C2", "a3", None, "a3"), + ("C2", "a4", True, "a4m2"), + ("C1x", "a1", True, "a1m1"), + ("C1x", "a2", True, "a2c1x"), + ("C1x", "a3", None, "a3"), + ("C1x", "a4", None, "a4"), ] for cn, sn, req, desc in expected: slot = view.induced_slot(sn, cn) assert req == slot.required, f"in: {cn}.{sn}" assert desc == slot.description, f"in: {cn}.{sn}" - assert slot.range == 'string', f"in: {cn}.{sn}" + assert slot.range == "string", f"in: {cn}.{sn}" def test_ambiguous_attributes(): - schema = SchemaDefinition(id='test', name='test') + schema = SchemaDefinition(id="test", name="test") view = SchemaView(schema) - a1 = SlotDefinition('a1', range='string') - a2 = SlotDefinition('a2', range='FooEnum') - a3 = SlotDefinition('a3', range='C3') - view.add_class(ClassDefinition('C1', attributes={a1.name: a1, a2.name: a2, a3.name: a3})) - a1x = SlotDefinition('a1', range='integer') - a2x = SlotDefinition('a2', range='BarEnum') - view.add_class(ClassDefinition('C2', attributes={a1x.name: a1x, a2x.name: a2x})) + a1 = SlotDefinition("a1", range="string") + a2 = SlotDefinition("a2", range="FooEnum") + a3 = SlotDefinition("a3", range="C3") + view.add_class(ClassDefinition("C1", attributes={a1.name: a1, a2.name: a2, a3.name: a3})) + a1x = SlotDefinition("a1", range="integer") + a2x = SlotDefinition("a2", range="BarEnum") + view.add_class(ClassDefinition("C2", attributes={a1x.name: a1x, a2x.name: a2x})) assert view.get_slot(a1.name).range is None assert view.get_slot(a2.name).range is None @@ -769,39 +800,39 @@ def test_ambiguous_attributes(): assert len(view.all_slots(attributes=False)) == 0 assert len(view.all_slots()) == 3 assert view.induced_slot(a3.name).range == a3.range - assert view.induced_slot(a1.name, 'C1').range == a1.range - assert view.induced_slot(a2.name, 'C1').range == a2.range - assert view.induced_slot(a1x.name, 'C2').range == a1x.range - assert view.induced_slot(a2x.name, 'C2').range == a2x.range + assert view.induced_slot(a1.name, "C1").range == a1.range + assert view.induced_slot(a2.name, "C1").range == a2.range + assert view.induced_slot(a1x.name, "C2").range == a1x.range + assert view.induced_slot(a2x.name, "C2").range == a2x.range def test_metamodel_in_schemaview(): - view = package_schemaview('linkml_runtime.linkml_model.meta') - assert 'meta' in view.imports_closure() - assert 'linkml:types' in view.imports_closure() - assert 'meta' in view.imports_closure(imports=False) - assert 'linkml:types' not in view.imports_closure(imports=False) + view = package_schemaview("linkml_runtime.linkml_model.meta") + assert "meta" in view.imports_closure() + assert "linkml:types" in view.imports_closure() + assert "meta" in view.imports_closure(imports=False) + assert "linkml:types" not in view.imports_closure(imports=False) assert len(view.imports_closure(imports=False)) == 1 all_classes = list(view.all_classes().keys()) all_classes_no_imports = list(view.all_classes(imports=False).keys()) - for cn in ['class_definition', 'type_definition', 'slot_definition']: + for cn in ["class_definition", "type_definition", "slot_definition"]: assert cn in all_classes assert cn in all_classes_no_imports - assert view.get_identifier_slot(cn).name == 'name' - for cn in ['annotation', 'extension']: + assert view.get_identifier_slot(cn).name == "name" + for cn in ["annotation", "extension"]: assert cn in all_classes, "imports should be included by default" assert cn not in all_classes_no_imports, "imported class unexpectedly included" - for sn in ['id', 'name', 'description']: + for sn in ["id", "name", "description"]: assert sn in view.all_slots() - for tn in ['uriorcurie', 'string', 'float']: + for tn in ["uriorcurie", "string", "float"]: assert tn in view.all_types() - for tn in ['uriorcurie', 'string', 'float']: + for tn in ["uriorcurie", "string", "float"]: assert tn not in view.all_types(imports=False) for cn, c in view.all_classes().items(): uri = view.get_uri(cn, expand=True) assert uri is not None - if cn not in ['structured_alias', 'UnitOfMeasure', 'ValidationReport', 'ValidationResult']: - assert 'https://w3id.org/linkml/' in uri + if cn not in ["structured_alias", "UnitOfMeasure", "ValidationReport", "ValidationResult"]: + assert "https://w3id.org/linkml/" in uri induced_slots = view.class_induced_slots(cn) for s in induced_slots: exp_slot_uri = view.get_uri(s, expand=True) @@ -834,7 +865,7 @@ def test_materialize_patterns_slot_usage(): sv = SchemaView(SCHEMA_WITH_STRUCTURED_PATTERNS) sv.materialize_patterns() - name_slot_usage = sv.get_class("FancyPersonInfo").slot_usage['name'] + name_slot_usage = sv.get_class("FancyPersonInfo").slot_usage["name"] assert name_slot_usage.pattern == r"\S+ \S+-\S+" @@ -842,7 +873,7 @@ def test_materialize_patterns_attribute(): sv = SchemaView(SCHEMA_WITH_STRUCTURED_PATTERNS) sv.materialize_patterns() - weight_attribute = sv.get_class('ClassWithAttributes').attributes['weight'] + weight_attribute = sv.get_class("ClassWithAttributes").attributes["weight"] assert weight_attribute.pattern == r"\d+[\.\d+] (kg|g|lbs|stone)" @@ -866,10 +897,11 @@ def test_mergeimports(): assert "was generated by" in slots_list prefixes_list = list(sv.schema.prefixes.keys()) - if 'schema' not in prefixes_list: - prefixes_list.append('schema') + if "schema" not in prefixes_list: + prefixes_list.append("schema") assert sorted(prefixes_list) == sorted( - ["pav", "dce", "lego", "linkml", "biolink", "ks", "RO", "BFO", "tax", "core", "prov", "xsd", "schema", "shex"]) + ["pav", "dce", "lego", "linkml", "biolink", "ks", "RO", "BFO", "tax", "core", "prov", "xsd", "schema", "shex"] + ) def test_is_inlined(): @@ -884,7 +916,7 @@ def test_is_inlined(): ("inlined_as_list_thing_without_id", True), ("an_integer", False), ("inlined_integer", False), - ("inlined_as_list_integer", False) + ("inlined_as_list_integer", False), ] for slot_name, expected_result in cases: slot = sv.get_slot(slot_name) @@ -909,8 +941,12 @@ def test_materialize_nonscalar_slot_usage(): assert cls.attributes["jog_wheels"].annotations.expected_value.value == "an integer between 0 and 4" assert cls.attributes["volume_faders"].annotations.expected_value.value == "an integer between 0 and 8" - assert cls.attributes["tempo"].examples == [Example(value='120.0'), Example(value='144.0'), Example(value='126.8'), - Example(value='102.6')] + assert cls.attributes["tempo"].examples == [ + Example(value="120.0"), + Example(value="144.0"), + Example(value="126.8"), + Example(value="102.6"), + ] assert cls.attributes["tempo"].annotations.expected_value.value == "a number between 0 and 200" assert cls.attributes["tempo"].annotations.preferred_unit.value == "BPM" assert cls.attributes["tempo"].domain_of == ["DJController"] diff --git a/tests/test_utils/test_version.py b/tests/test_utils/test_version.py index 7df18eab..49ef1c4a 100644 --- a/tests/test_utils/test_version.py +++ b/tests/test_utils/test_version.py @@ -2,6 +2,7 @@ import linkml_runtime + class TestPackageVersion(unittest.TestCase): def test_package_version(self): self.assertIsNotNone(linkml_runtime.__version__) diff --git a/tests/test_utils/test_walker_utils.py b/tests/test_utils/test_walker_utils.py index 195b1100..5137fe57 100644 --- a/tests/test_utils/test_walker_utils.py +++ b/tests/test_utils/test_walker_utils.py @@ -4,15 +4,14 @@ from jsonasobj2 import as_dict -from linkml_runtime.linkml_model import SchemaDefinition, ClassDefinition +from linkml_runtime.linkml_model import ClassDefinition, SchemaDefinition from linkml_runtime.utils.walker_utils import traverse_object_tree from linkml_runtime.utils.yamlutils import YAMLRoot - from tests.test_utils import INPUT_DIR from tests.test_utils.test_ruleutils import yaml_loader -SCHEMA = os.path.join(INPUT_DIR, 'kitchen_sink_noimports.yaml') -INSERTED_COMMENT = 'INSERTED COMMENT' +SCHEMA = os.path.join(INPUT_DIR, "kitchen_sink_noimports.yaml") +INSERTED_COMMENT = "INSERTED COMMENT" def count_classes(obj: YAMLRoot) -> int: @@ -83,7 +82,7 @@ def tr(in_obj: YAMLRoot): self.assertNotEqual(orig, obj) self.assertEqual(obj_tr, obj) obj = SchemaDefinition(**as_dict(obj)) - assert INSERTED_COMMENT in obj.classes['Person'].comments + assert INSERTED_COMMENT in obj.classes["Person"].comments def test_non_mutating_transformer(self): """ @@ -109,8 +108,8 @@ def tr(in_obj: YAMLRoot): self.assertNotEqual(obj_tr, orig) self.assertNotEqual(obj_tr, obj) obj_tr = SchemaDefinition(**as_dict(obj_tr)) - assert INSERTED_COMMENT in obj_tr.classes['Person'].comments + assert INSERTED_COMMENT in obj_tr.classes["Person"].comments -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_utils/test_yaml_utils.py b/tests/test_utils/test_yaml_utils.py index e10553cb..6ad93b9a 100644 --- a/tests/test_utils/test_yaml_utils.py +++ b/tests/test_utils/test_yaml_utils.py @@ -11,19 +11,19 @@ class YamlUtilTestCase(TestEnvironmentTestCase): env = env def test_dupcheck_loader(self): - """ Make sure the duplicate checker finds duplicates """ - with open(env.input_path('yaml1.yaml')) as f: + """Make sure the duplicate checker finds duplicates""" + with open(env.input_path("yaml1.yaml")) as f: y1 = yaml.safe_load(f) - self.assertEqual(17, y1['f1']) - with open(env.input_path('yaml1.yaml')) as f: + self.assertEqual(17, y1["f1"]) + with open(env.input_path("yaml1.yaml")) as f: with self.assertRaises(ValueError): yaml.load(f, DupCheckYamlLoader) - with open(env.input_path('yaml2.yaml')) as f: + with open(env.input_path("yaml2.yaml")) as f: with self.assertRaises(ValueError): yaml.load(f, DupCheckYamlLoader) - with open(env.input_path('schema1.yaml')) as f: + with open(env.input_path("schema1.yaml")) as f: s1 = yaml.load(f, DupCheckYamlLoader) - self.assertEqual('schema1', s1['name']) + self.assertEqual("schema1", s1["name"]) def test_line_numbers(self): s = """ @@ -36,16 +36,14 @@ def test_line_numbers(self): """ obj = yaml.load(s, DupCheckYamlLoader) cases = [ - ('name', 1), - ('info', 2), - ('x', 3), - ('l', 6), + ("name", 1), + ("info", 2), + ("x", 3), + ("l", 6), ] key_to_lines = [(k, k._s.line) for k in obj.keys()] self.assertCountEqual(cases, key_to_lines) - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tox.ini b/tox.ini index e57a137a..3c3587ee 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,32 @@ [tox] envlist = py39, py310, py311, py312, py313 -[testenv] +[testenv:py] skip_install = true allowlist_externals = poetry commands_pre = poetry install commands = poetry run pytest + +[testenv:lint] +skip_install = true +deps = + ruff + black + codespell +commands = + ruff check + black --check --diff . + codespell + +[testenv:format] +skip_install = true +deps = + ruff + black + codespell +commands = + black . + ruff check --fix + codespell