linkml 1.8.2__tar.gz → 1.8.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {linkml-1.8.2 → linkml-1.8.3}/PKG-INFO +1 -1
- {linkml-1.8.2 → linkml-1.8.3}/linkml/cli/main.py +4 -0
- linkml-1.8.3/linkml/generators/common/ifabsent_processor.py +286 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/jsonldcontextgen.py +0 -1
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/pydanticgen.py +11 -8
- linkml-1.8.3/linkml/generators/python/__init__.py +1 -0
- linkml-1.8.3/linkml/generators/python/python_ifabsent_processor.py +92 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pythongen.py +7 -21
- linkml-1.8.3/linkml/generators/shacl/__init__.py +1 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/shacl/shacl_data_type.py +1 -1
- linkml-1.8.3/linkml/generators/shacl/shacl_ifabsent_processor.py +89 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/shaclgen.py +5 -3
- {linkml-1.8.2 → linkml-1.8.3}/pyproject.toml +2 -1
- {linkml-1.8.2 → linkml-1.8.3}/setup.py +2 -1
- linkml-1.8.2/linkml/generators/shacl/__init__.py +0 -3
- linkml-1.8.2/linkml/generators/shacl/ifabsent_processor.py +0 -59
- linkml-1.8.2/linkml/utils/ifabsent_functions.py +0 -138
- {linkml-1.8.2 → linkml-1.8.3}/LICENSE +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/README.md +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/_version.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/cli/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/cli/__main__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/PythonGenNotes.md +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/README.md +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/common/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/common/build.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/common/lifecycle.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/common/template.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/common/type_designators.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/csvgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/class.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/class_diagram.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/common_metadata.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/enum.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/index.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/index.tex.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/schema.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/slot.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/subset.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen/type.md.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/docgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/dotgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/erdiagramgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/excelgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/golanggen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/golrgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/graphqlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/javagen/example_template.java.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/javagen/java_record_template.jinja2 +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/javagen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/jsonldgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/jsonschemagen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/legacy/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/linkmlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/markdowngen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/namespacegen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/oocodegen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/owlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/plantumlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/prefixmapgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/projectgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/protogen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/array.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/black.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/build.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/includes.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/template.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/attribute.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/base_model.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/class.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/conditional_import.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/enum.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/footer.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/imports.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/module.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/pydanticgen/templates/validator.py.jinja +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/rdfgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/shexgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sparqlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sqlalchemy/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sqlalchemy/sqlalchemy_declarative_template.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sqlalchemy/sqlalchemy_imperative_template.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sqlalchemygen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sqltablegen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/sssomgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/string_template.md +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/summarygen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/terminusdbgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/typescriptgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/yamlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/generators/yumlgen.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/cli.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/config/datamodel/.linkmllint.yaml +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/config/datamodel/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/config/datamodel/config.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/config/datamodel/config.yaml +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/config/default.yaml +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/config/recommended.yaml +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/formatters/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/formatters/formatter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/formatters/json_formatter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/formatters/markdown_formatter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/formatters/terminal_formatter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/formatters/tsv_formatter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/linter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/linter/rules.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/reporting/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/reporting/model.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/transformers/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/transformers/logical_model_transformer.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/transformers/model_transformer.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/transformers/relmodel_transformer.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/transformers/schema_renamer.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/cli_utils.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/converter.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/datautils.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/datavalidator.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/deprecation.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/execute_tutorial.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/generator.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/helpers.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/logictools.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/mergeutils.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/rawloader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/schema_builder.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/schema_fixer.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/schemaloader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/schemasynopsis.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/sqlutils.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/typereferences.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/utils/validation.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/cli.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/loaders/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/loaders/delimited_file_loader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/loaders/json_loader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/loaders/loader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/loaders/passthrough_loader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/loaders/yaml_loader.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/plugins/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/plugins/jsonschema_validation_plugin.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/plugins/pydantic_validation_plugin.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/plugins/recommended_slots_plugin.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/plugins/shacl_validation_plugin.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/plugins/validation_plugin.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/report.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/validation_context.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validator/validator.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validators/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validators/jsonschemavalidator.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/validators/sparqlvalidator.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/workspaces/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/workspaces/datamodel/__init__.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/workspaces/datamodel/workspaces.py +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/workspaces/datamodel/workspaces.yaml +0 -0
- {linkml-1.8.2 → linkml-1.8.3}/linkml/workspaces/example_runner.py +0 -0
@@ -6,6 +6,7 @@ Gathers all the other linkml click entrypoints and puts them under ``linkml`` :)
|
|
6
6
|
|
7
7
|
import click
|
8
8
|
|
9
|
+
from linkml._version import __version__
|
9
10
|
from linkml.generators.csvgen import cli as gen_csv
|
10
11
|
from linkml.generators.docgen import cli as gen_doc
|
11
12
|
from linkml.generators.dotgen import cli as gen_graphviz
|
@@ -54,6 +55,7 @@ from linkml.workspaces.example_runner import cli as linkml_run_examples
|
|
54
55
|
|
55
56
|
|
56
57
|
@click.group()
|
58
|
+
@click.version_option(__version__, "-V", "--version")
|
57
59
|
def linkml():
|
58
60
|
"""
|
59
61
|
LinkML: A flexible linked data modeling language
|
@@ -61,6 +63,7 @@ def linkml():
|
|
61
63
|
|
62
64
|
|
63
65
|
@linkml.group()
|
66
|
+
@click.version_option(__version__, "-V", "--version")
|
64
67
|
def generate():
|
65
68
|
"""
|
66
69
|
Generate formats from a LinkML schema
|
@@ -68,6 +71,7 @@ def generate():
|
|
68
71
|
|
69
72
|
|
70
73
|
@linkml.group()
|
74
|
+
@click.version_option(__version__, "-V", "--version")
|
71
75
|
def dev():
|
72
76
|
"""
|
73
77
|
Helper tools for linkml development
|
@@ -0,0 +1,286 @@
|
|
1
|
+
import abc
|
2
|
+
import re
|
3
|
+
from abc import ABC
|
4
|
+
from typing import Any, Optional
|
5
|
+
|
6
|
+
from linkml_runtime import SchemaView
|
7
|
+
from linkml_runtime.linkml_model import (
|
8
|
+
Boolean,
|
9
|
+
ClassDefinition,
|
10
|
+
Date,
|
11
|
+
Datetime,
|
12
|
+
Decimal,
|
13
|
+
Double,
|
14
|
+
EnumDefinitionName,
|
15
|
+
Float,
|
16
|
+
Integer,
|
17
|
+
SlotDefinition,
|
18
|
+
String,
|
19
|
+
Time,
|
20
|
+
Uri,
|
21
|
+
)
|
22
|
+
from linkml_runtime.linkml_model.types import (
|
23
|
+
Curie,
|
24
|
+
DateOrDatetime,
|
25
|
+
Jsonpath,
|
26
|
+
Jsonpointer,
|
27
|
+
Ncname,
|
28
|
+
Nodeidentifier,
|
29
|
+
Objectidentifier,
|
30
|
+
Sparqlpath,
|
31
|
+
Uriorcurie,
|
32
|
+
)
|
33
|
+
|
34
|
+
|
35
|
+
class IfAbsentProcessor(ABC):
|
36
|
+
"""
|
37
|
+
Processes value of ifabsent slot.
|
38
|
+
|
39
|
+
See `<https://w3id.org/linkml/ifabsent>`_.
|
40
|
+
"""
|
41
|
+
|
42
|
+
ifabsent_regex = re.compile("""(?:(?P<type>\w+)\()?[\"\']?(?P<default_value>[^\(\)\"\')]*)[\"\']?\)?""")
|
43
|
+
|
44
|
+
def __init__(self, schema_view: SchemaView):
|
45
|
+
self.schema_view = schema_view
|
46
|
+
|
47
|
+
def process_slot(self, slot: SlotDefinition, cls: ClassDefinition) -> Optional[str]:
|
48
|
+
if slot.ifabsent:
|
49
|
+
ifabsent_match = self.ifabsent_regex.search(slot.ifabsent)
|
50
|
+
ifabsent_default_value = ifabsent_match.group("default_value")
|
51
|
+
|
52
|
+
return self._map_to_default_value(slot, ifabsent_default_value, cls)
|
53
|
+
|
54
|
+
return None
|
55
|
+
|
56
|
+
def _map_to_default_value(
|
57
|
+
self, slot: SlotDefinition, ifabsent_default_value: Any, cls: ClassDefinition
|
58
|
+
) -> Optional[str]:
|
59
|
+
# Used to manage specific cases that aren't generic
|
60
|
+
mapped, custom_default_value = self.map_custom_default_values(ifabsent_default_value, slot, cls)
|
61
|
+
if mapped:
|
62
|
+
return custom_default_value
|
63
|
+
|
64
|
+
if slot.range == String.type_name:
|
65
|
+
return self.map_string_default_value(ifabsent_default_value, slot, cls)
|
66
|
+
|
67
|
+
if slot.range == Boolean.type_name:
|
68
|
+
if re.match(r"^[Tt]rue$", ifabsent_default_value):
|
69
|
+
return self.map_boolean_true_default_value(slot, cls)
|
70
|
+
elif re.match(r"^[Ff]alse$", ifabsent_default_value):
|
71
|
+
return self.map_boolean_false_default_value(slot, cls)
|
72
|
+
else:
|
73
|
+
raise ValueError(
|
74
|
+
f"The ifabsent value `{slot.ifabsent}` of the `{slot.name}` slot does not match a valid boolean "
|
75
|
+
f"value"
|
76
|
+
)
|
77
|
+
|
78
|
+
if slot.range == Integer.type_name:
|
79
|
+
return self.map_integer_default_value(ifabsent_default_value, slot, cls)
|
80
|
+
|
81
|
+
if slot.range == Float.type_name:
|
82
|
+
return self.map_float_default_value(ifabsent_default_value, slot, cls)
|
83
|
+
|
84
|
+
if slot.range == Double.type_name:
|
85
|
+
return self.map_double_default_value(ifabsent_default_value, slot, cls)
|
86
|
+
|
87
|
+
if slot.range == Decimal.type_name:
|
88
|
+
return self.map_decimal_default_value(ifabsent_default_value, slot, cls)
|
89
|
+
|
90
|
+
if slot.range == Time.type_name:
|
91
|
+
match = re.match(r"^(\d{2}):(\d{2}):(\d{2}).*$", ifabsent_default_value)
|
92
|
+
if match:
|
93
|
+
return self.map_time_default_value(match[1], match[2], match[3], slot, cls)
|
94
|
+
else:
|
95
|
+
raise ValueError(
|
96
|
+
f"The ifabsent value `{slot.ifabsent}` of the `{slot.name}` slot does not match a valid time value"
|
97
|
+
)
|
98
|
+
|
99
|
+
# TODO manage timezones and offsets
|
100
|
+
if slot.range == Date.type_name:
|
101
|
+
match = re.match(r"^(\d{4})-(\d{2})-(\d{2})$", ifabsent_default_value)
|
102
|
+
if match:
|
103
|
+
return self.map_date_default_value(match[1], match[2], match[3], slot, cls)
|
104
|
+
else:
|
105
|
+
raise ValueError(
|
106
|
+
f"The ifabsent value `{slot.ifabsent}` of the `{slot.name}` slot does not match a valid date value"
|
107
|
+
)
|
108
|
+
|
109
|
+
# TODO manage timezones and offsets
|
110
|
+
if slot.range == Datetime.type_name:
|
111
|
+
match = re.match(r"^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).*$", ifabsent_default_value)
|
112
|
+
if match:
|
113
|
+
return self.map_datetime_default_value(
|
114
|
+
match[1], match[2], match[3], match[4], match[5], match[6], slot, cls
|
115
|
+
)
|
116
|
+
else:
|
117
|
+
raise ValueError(
|
118
|
+
f"The ifabsent value `{slot.ifabsent}` of the `{slot.name}` slot does not match a valid datetime "
|
119
|
+
f"value"
|
120
|
+
)
|
121
|
+
|
122
|
+
# TODO manage timezones and offsets
|
123
|
+
if slot.range == DateOrDatetime.type_name:
|
124
|
+
match = re.match(r"^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2}):(\d{2}))?.*$", ifabsent_default_value)
|
125
|
+
if match and (match[4] is None or match[5] is None or match[6] is None):
|
126
|
+
return self.map_date_default_value(match[1], match[2], match[3], slot, cls)
|
127
|
+
elif match:
|
128
|
+
return self.map_datetime_default_value(
|
129
|
+
match[1], match[2], match[3], match[4], match[5], match[6], slot, cls
|
130
|
+
)
|
131
|
+
else:
|
132
|
+
raise ValueError(
|
133
|
+
f"The ifabsent value `{slot.ifabsent}` of the `{slot.name}` slot does not match a valid date or "
|
134
|
+
f"datetime value"
|
135
|
+
)
|
136
|
+
|
137
|
+
if slot.range == Uri.type_name:
|
138
|
+
return self.map_uri_default_value(ifabsent_default_value, slot, cls)
|
139
|
+
|
140
|
+
if slot.range == Curie.type_name:
|
141
|
+
return self.map_curie_default_value(ifabsent_default_value, slot, cls)
|
142
|
+
|
143
|
+
if slot.range == Uriorcurie.type_name:
|
144
|
+
return self.map_uri_or_curie_default_value(ifabsent_default_value, slot, cls)
|
145
|
+
|
146
|
+
if slot.range == Ncname.type_name:
|
147
|
+
return self.map_nc_name_default_value(ifabsent_default_value, slot, cls)
|
148
|
+
|
149
|
+
if slot.range == Objectidentifier.type_name:
|
150
|
+
return self.map_object_identifier_default_value(ifabsent_default_value, slot, cls)
|
151
|
+
|
152
|
+
if slot.range == Nodeidentifier.type_name:
|
153
|
+
return self.map_node_identifier_default_value(ifabsent_default_value, slot, cls)
|
154
|
+
|
155
|
+
if slot.range == Jsonpointer.type_name:
|
156
|
+
return self.map_json_pointer_default_value(ifabsent_default_value, slot, cls)
|
157
|
+
|
158
|
+
if slot.range == Jsonpath.type_name:
|
159
|
+
return self.map_json_path_default_value(ifabsent_default_value, slot, cls)
|
160
|
+
|
161
|
+
if slot.range == Sparqlpath.type_name:
|
162
|
+
return self.map_sparql_path_default_value(ifabsent_default_value, slot, cls)
|
163
|
+
|
164
|
+
# -----------------------
|
165
|
+
# Enum slot ranges
|
166
|
+
# -----------------------
|
167
|
+
|
168
|
+
for enum_name, enum in self.schema_view.all_enums().items():
|
169
|
+
if enum_name == slot.range:
|
170
|
+
for permissible_value_name, permissible_value in enum.permissible_values.items():
|
171
|
+
if permissible_value_name == ifabsent_default_value:
|
172
|
+
return self.map_enum_default_value(enum_name, permissible_value_name, slot, cls)
|
173
|
+
|
174
|
+
raise ValueError(f"The ifabsent value `{slot.ifabsent}` of the `{slot.name}` slot could not be processed")
|
175
|
+
|
176
|
+
@abc.abstractmethod
|
177
|
+
def map_custom_default_values(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition) -> (bool, str):
|
178
|
+
"""
|
179
|
+
Maps custom default values that aren't generic behaviours.
|
180
|
+
|
181
|
+
@param default_value: the default value extracted from the ifabsent attribute
|
182
|
+
@param slot: the definition of the slot
|
183
|
+
@param cls: the definition of the class
|
184
|
+
@return: a boolean that indicates if the value has been mapped followed by the mapped value
|
185
|
+
"""
|
186
|
+
return False, None
|
187
|
+
|
188
|
+
@abc.abstractmethod
|
189
|
+
def map_string_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
190
|
+
raise NotImplementedError()
|
191
|
+
|
192
|
+
@abc.abstractmethod
|
193
|
+
def map_integer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
194
|
+
raise NotImplementedError()
|
195
|
+
|
196
|
+
@abc.abstractmethod
|
197
|
+
def map_boolean_true_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
198
|
+
raise NotImplementedError()
|
199
|
+
|
200
|
+
@abc.abstractmethod
|
201
|
+
def map_boolean_false_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
202
|
+
raise NotImplementedError()
|
203
|
+
|
204
|
+
@abc.abstractmethod
|
205
|
+
def map_float_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
206
|
+
raise NotImplementedError()
|
207
|
+
|
208
|
+
@abc.abstractmethod
|
209
|
+
def map_double_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
210
|
+
raise NotImplementedError()
|
211
|
+
|
212
|
+
@abc.abstractmethod
|
213
|
+
def map_decimal_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
214
|
+
raise NotImplementedError()
|
215
|
+
|
216
|
+
@abc.abstractmethod
|
217
|
+
def map_time_default_value(self, hour: str, minutes: str, seconds: str, slot: SlotDefinition, cls: ClassDefinition):
|
218
|
+
raise NotImplementedError()
|
219
|
+
|
220
|
+
@abc.abstractmethod
|
221
|
+
def map_date_default_value(self, year: str, month: str, day: str, slot: SlotDefinition, cls: ClassDefinition):
|
222
|
+
raise NotImplementedError()
|
223
|
+
|
224
|
+
@abc.abstractmethod
|
225
|
+
def map_datetime_default_value(
|
226
|
+
self,
|
227
|
+
year: str,
|
228
|
+
month: str,
|
229
|
+
day: str,
|
230
|
+
hour: str,
|
231
|
+
minutes: str,
|
232
|
+
seconds: str,
|
233
|
+
slot: SlotDefinition,
|
234
|
+
cls: ClassDefinition,
|
235
|
+
):
|
236
|
+
raise NotImplementedError()
|
237
|
+
|
238
|
+
@abc.abstractmethod
|
239
|
+
def map_uri_or_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
240
|
+
raise NotImplementedError()
|
241
|
+
|
242
|
+
@abc.abstractmethod
|
243
|
+
def map_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
244
|
+
raise NotImplementedError()
|
245
|
+
|
246
|
+
@abc.abstractmethod
|
247
|
+
def map_uri_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
248
|
+
raise NotImplementedError()
|
249
|
+
|
250
|
+
@abc.abstractmethod
|
251
|
+
def map_nc_name_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
252
|
+
raise NotImplementedError()
|
253
|
+
|
254
|
+
@abc.abstractmethod
|
255
|
+
def map_object_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
256
|
+
raise NotImplementedError()
|
257
|
+
|
258
|
+
@abc.abstractmethod
|
259
|
+
def map_node_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
260
|
+
raise NotImplementedError()
|
261
|
+
|
262
|
+
@abc.abstractmethod
|
263
|
+
def map_json_pointer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
264
|
+
raise NotImplementedError()
|
265
|
+
|
266
|
+
@abc.abstractmethod
|
267
|
+
def map_json_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
268
|
+
raise NotImplementedError()
|
269
|
+
|
270
|
+
@abc.abstractmethod
|
271
|
+
def map_sparql_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
272
|
+
raise NotImplementedError()
|
273
|
+
|
274
|
+
@abc.abstractmethod
|
275
|
+
def map_enum_default_value(
|
276
|
+
self, enum_name: EnumDefinitionName, permissible_value_name: str, slot: SlotDefinition, cls: ClassDefinition
|
277
|
+
):
|
278
|
+
raise NotImplementedError()
|
279
|
+
|
280
|
+
def _uri_for(self, s: str) -> str:
|
281
|
+
uri = str(self.schema_view.namespaces().uri_for(s))
|
282
|
+
return self.schema_view.namespaces().curie_for(uri, True, True) or self._strval(uri)
|
283
|
+
|
284
|
+
def _strval(self, txt: str) -> str:
|
285
|
+
txt = str(txt).replace('"', '\\"')
|
286
|
+
return f'"{txt}"'
|
@@ -41,9 +41,9 @@ from linkml.generators.pydanticgen.template import (
|
|
41
41
|
PydanticModule,
|
42
42
|
PydanticTemplateModel,
|
43
43
|
)
|
44
|
+
from linkml.generators.python.python_ifabsent_processor import PythonIfAbsentProcessor
|
44
45
|
from linkml.utils import deprecation_warning
|
45
46
|
from linkml.utils.generator import shared_arguments
|
46
|
-
from linkml.utils.ifabsent_functions import ifabsent_value_declaration
|
47
47
|
|
48
48
|
if int(PYDANTIC_VERSION[0]) == 1:
|
49
49
|
deprecation_warning("pydantic-v1")
|
@@ -67,7 +67,9 @@ def _get_pyrange(t: TypeDefinition, sv: SchemaView) -> str:
|
|
67
67
|
DEFAULT_IMPORTS = (
|
68
68
|
Imports()
|
69
69
|
+ Import(module="__future__", objects=[ObjectImport(name="annotations")])
|
70
|
-
+ Import(
|
70
|
+
+ Import(
|
71
|
+
module="datetime", objects=[ObjectImport(name="datetime"), ObjectImport(name="date"), ObjectImport(name="time")]
|
72
|
+
)
|
71
73
|
+ Import(module="decimal", objects=[ObjectImport(name="Decimal")])
|
72
74
|
+ Import(module="enum", objects=[ObjectImport(name="Enum")])
|
73
75
|
+ Import(module="re")
|
@@ -526,6 +528,7 @@ class PydanticGenerator(OOCodeGenerator, LifecycleMixin):
|
|
526
528
|
"""
|
527
529
|
if self._predefined_slot_values is None:
|
528
530
|
sv = self.schemaview
|
531
|
+
ifabsent_processor = PythonIfAbsentProcessor(sv)
|
529
532
|
slot_values = defaultdict(dict)
|
530
533
|
for class_def in sv.all_classes().values():
|
531
534
|
for slot_name in sv.class_slots(class_def.name):
|
@@ -541,10 +544,10 @@ class PydanticGenerator(OOCodeGenerator, LifecycleMixin):
|
|
541
544
|
slot.name
|
542
545
|
]
|
543
546
|
elif slot.ifabsent is not None:
|
544
|
-
value =
|
547
|
+
value = ifabsent_processor.process_slot(slot, class_def)
|
545
548
|
slot_values[camelcase(class_def.name)][slot.name] = value
|
546
549
|
|
547
|
-
|
550
|
+
self._predefined_slot_values = slot_values
|
548
551
|
|
549
552
|
return self._predefined_slot_values
|
550
553
|
|
@@ -1061,7 +1064,7 @@ class PydanticGenerator(OOCodeGenerator, LifecycleMixin):
|
|
1061
1064
|
# interpret all imported schema paths as relative to that
|
1062
1065
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
1063
1066
|
serialized = generator.serialize(rendered_module=rendered)
|
1064
|
-
with open(output_path, "w") as ofile:
|
1067
|
+
with open(output_path, "w", encoding="utf-8") as ofile:
|
1065
1068
|
ofile.write(serialized)
|
1066
1069
|
|
1067
1070
|
results.append(
|
@@ -1080,7 +1083,7 @@ class PydanticGenerator(OOCodeGenerator, LifecycleMixin):
|
|
1080
1083
|
rel_path = _import_to_path(generated_import.module)
|
1081
1084
|
abs_path = (output_path.parent / rel_path).resolve()
|
1082
1085
|
abs_path.parent.mkdir(parents=True, exist_ok=True)
|
1083
|
-
with open(abs_path, "w") as ofile:
|
1086
|
+
with open(abs_path, "w", encoding="utf-8") as ofile:
|
1084
1087
|
ofile.write(serialized)
|
1085
1088
|
|
1086
1089
|
results.append(
|
@@ -1123,7 +1126,7 @@ def _ensure_inits(paths: List[Path]):
|
|
1123
1126
|
common_path = Path(os.path.commonpath(paths))
|
1124
1127
|
|
1125
1128
|
if not (ipath := (common_path / "__init__.py")).exists():
|
1126
|
-
with open(ipath, "w") as ifile:
|
1129
|
+
with open(ipath, "w", encoding="utf-8") as ifile:
|
1127
1130
|
ifile.write(" \n")
|
1128
1131
|
|
1129
1132
|
for path in paths:
|
@@ -1131,7 +1134,7 @@ def _ensure_inits(paths: List[Path]):
|
|
1131
1134
|
path = path.parent
|
1132
1135
|
while path != common_path:
|
1133
1136
|
if not (ipath := (path / "__init__.py")).exists():
|
1134
|
-
with open(ipath, "w") as ifile:
|
1137
|
+
with open(ipath, "w", encoding="utf-8") as ifile:
|
1135
1138
|
ifile.write(" \n")
|
1136
1139
|
path = path.parent
|
1137
1140
|
|
@@ -0,0 +1 @@
|
|
1
|
+
__all__ = ["python_ifabsent_processor"]
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from linkml_runtime.linkml_model import (
|
2
|
+
ClassDefinition,
|
3
|
+
EnumDefinitionName,
|
4
|
+
SlotDefinition,
|
5
|
+
)
|
6
|
+
|
7
|
+
from linkml.generators.common.ifabsent_processor import IfAbsentProcessor
|
8
|
+
|
9
|
+
|
10
|
+
class PythonIfAbsentProcessor(IfAbsentProcessor):
|
11
|
+
UNIMPLEMENTED_DEFAULT_VALUES = ["class_curie", "class_uri", "slot_uri", "slot_curie", "default_range", "default_ns"]
|
12
|
+
|
13
|
+
def map_custom_default_values(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition) -> (bool, str):
|
14
|
+
if default_value in self.UNIMPLEMENTED_DEFAULT_VALUES:
|
15
|
+
return True, None
|
16
|
+
|
17
|
+
if default_value == "bnode":
|
18
|
+
return True, "bnode()"
|
19
|
+
|
20
|
+
return False, None
|
21
|
+
|
22
|
+
def map_string_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
23
|
+
return self._strval(default_value)
|
24
|
+
|
25
|
+
def map_boolean_true_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
26
|
+
return "True"
|
27
|
+
|
28
|
+
def map_boolean_false_default_value(self, slot: SlotDefinition, cls: ClassDefinition):
|
29
|
+
return "False"
|
30
|
+
|
31
|
+
def map_integer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
32
|
+
return default_value
|
33
|
+
|
34
|
+
def map_float_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
35
|
+
return default_value
|
36
|
+
|
37
|
+
def map_double_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
38
|
+
return default_value
|
39
|
+
|
40
|
+
def map_decimal_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
41
|
+
return default_value
|
42
|
+
|
43
|
+
def map_time_default_value(self, hour: str, minutes: str, seconds: str, slot: SlotDefinition, cls: ClassDefinition):
|
44
|
+
return f"time({int(hour)}, {int(minutes)}, {int(seconds)})"
|
45
|
+
|
46
|
+
def map_date_default_value(self, year: str, month: str, day: str, slot: SlotDefinition, cls: ClassDefinition):
|
47
|
+
return f"date({int(year)}, {int(month)}, {int(day)})"
|
48
|
+
|
49
|
+
def map_datetime_default_value(
|
50
|
+
self,
|
51
|
+
year: str,
|
52
|
+
month: str,
|
53
|
+
day: str,
|
54
|
+
hour: str,
|
55
|
+
minutes: str,
|
56
|
+
seconds: str,
|
57
|
+
slot: SlotDefinition,
|
58
|
+
cls: ClassDefinition,
|
59
|
+
):
|
60
|
+
return f"datetime({int(year)}, {int(month)}, {int(day)}, " f"{int(hour)}, {int(minutes)}, {int(seconds)})"
|
61
|
+
|
62
|
+
def map_uri_or_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
63
|
+
return self._uri_for(default_value)
|
64
|
+
|
65
|
+
def map_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
66
|
+
return self._uri_for(default_value)
|
67
|
+
|
68
|
+
def map_uri_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
69
|
+
return self._uri_for(default_value)
|
70
|
+
|
71
|
+
def map_enum_default_value(
|
72
|
+
self, enum_name: EnumDefinitionName, permissible_value_name: str, slot: SlotDefinition, cls: ClassDefinition
|
73
|
+
):
|
74
|
+
return f"{enum_name}.{permissible_value_name}"
|
75
|
+
|
76
|
+
def map_nc_name_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
77
|
+
raise NotImplementedError()
|
78
|
+
|
79
|
+
def map_object_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
80
|
+
raise NotImplementedError()
|
81
|
+
|
82
|
+
def map_node_identifier_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
83
|
+
raise NotImplementedError()
|
84
|
+
|
85
|
+
def map_json_pointer_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
86
|
+
raise NotImplementedError()
|
87
|
+
|
88
|
+
def map_json_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
89
|
+
raise NotImplementedError()
|
90
|
+
|
91
|
+
def map_sparql_path_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
92
|
+
raise NotImplementedError()
|
@@ -29,8 +29,8 @@ from rdflib import URIRef
|
|
29
29
|
|
30
30
|
import linkml
|
31
31
|
from linkml._version import __version__
|
32
|
+
from linkml.generators.python.python_ifabsent_processor import PythonIfAbsentProcessor
|
32
33
|
from linkml.utils.generator import Generator, shared_arguments
|
33
|
-
from linkml.utils.ifabsent_functions import ifabsent_postinit_declaration, ifabsent_value_declaration
|
34
34
|
|
35
35
|
|
36
36
|
@dataclass
|
@@ -70,6 +70,7 @@ class PythonGenerator(Generator):
|
|
70
70
|
self.schema = str(self.schema)
|
71
71
|
self.sourcefile = self.schema
|
72
72
|
self.schemaview = SchemaView(self.schema, base_dir=self.base_dir)
|
73
|
+
self.ifabsent_processor = PythonIfAbsentProcessor(self.schemaview)
|
73
74
|
super().__post_init__()
|
74
75
|
if self.format is None:
|
75
76
|
self.format = self.valid_formats[0]
|
@@ -153,7 +154,7 @@ import re
|
|
153
154
|
from jsonasobj2 import JsonObj, as_dict
|
154
155
|
from typing import Optional, List, Union, Dict, ClassVar, Any
|
155
156
|
from dataclasses import dataclass
|
156
|
-
from datetime import date, datetime
|
157
|
+
from datetime import date, datetime, time
|
157
158
|
{enumimports}
|
158
159
|
from linkml_runtime.utils.slot import Slot
|
159
160
|
from linkml_runtime.utils.metamodelcore import empty_list, empty_dict, bnode
|
@@ -515,7 +516,7 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
515
516
|
|
516
517
|
return "\n\t".join(initializers)
|
517
518
|
|
518
|
-
def gen_class_variable(self, cls: ClassDefinition, slot: SlotDefinition, can_be_positional: bool) -> str:
|
519
|
+
def gen_class_variable(self, cls: ClassDefinition, slot: SlotDefinition, can_be_positional: bool = False) -> str:
|
519
520
|
"""
|
520
521
|
Generate a class variable declaration for the supplied slot. Note: the can_be_positional attribute works,
|
521
522
|
but it makes tag/value lists unduly complex, as you can't load them with tag=..., value=... -- you HAVE
|
@@ -527,12 +528,9 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
527
528
|
:param can_be_positional: True means that positional parameters are allowed.
|
528
529
|
:return: Initializer string
|
529
530
|
"""
|
530
|
-
can_be_positional = False # Force everything to be tag values
|
531
531
|
slotname = self.slot_name(slot.name)
|
532
532
|
slot_range, default_val = self.range_cardinality(slot, cls, can_be_positional)
|
533
|
-
ifabsent_text = (
|
534
|
-
ifabsent_value_declaration(slot.ifabsent, self, cls, slot) if slot.ifabsent is not None else None
|
535
|
-
)
|
533
|
+
ifabsent_text = self.ifabsent_processor.process_slot(slot, cls) if slot.ifabsent is not None else None
|
536
534
|
if ifabsent_text is not None:
|
537
535
|
default = f"= {ifabsent_text}"
|
538
536
|
else:
|
@@ -637,15 +635,6 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
637
635
|
|
638
636
|
def gen_postinits(self, cls: ClassDefinition) -> str:
|
639
637
|
"""Generate all the typing and existence checks post initialize"""
|
640
|
-
post_inits_pre_super = []
|
641
|
-
for slot in self.domain_slots(cls):
|
642
|
-
if slot.ifabsent:
|
643
|
-
dflt = ifabsent_postinit_declaration(slot.ifabsent, self, cls, slot)
|
644
|
-
|
645
|
-
if dflt and dflt != "None":
|
646
|
-
post_inits_pre_super.append(f"if self.{self.slot_name(slot.name)} is None:")
|
647
|
-
post_inits_pre_super.append(f"\tself.{self.slot_name(slot.name)} = {dflt}")
|
648
|
-
|
649
638
|
post_inits = []
|
650
639
|
if not (cls.mixin or cls.abstract):
|
651
640
|
pkeys = self.primary_keys_for(cls)
|
@@ -676,20 +665,17 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
|
|
676
665
|
if slot.name not in domain_slot_names and slot.designates_type:
|
677
666
|
post_inits_designators.append(self.gen_postinit(cls, slot))
|
678
667
|
|
679
|
-
post_inits_pre_super_line = "\n\t\t".join([p for p in post_inits_pre_super if p]) + (
|
680
|
-
"\n\t\t" if post_inits_pre_super else ""
|
681
|
-
)
|
682
668
|
post_inits_post_super_line = "\n\t\t".join(post_inits_designators)
|
683
669
|
post_inits_line = "\n\t\t".join([p for p in post_inits if p])
|
684
670
|
return (
|
685
671
|
(
|
686
672
|
f"""
|
687
673
|
def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
|
688
|
-
{
|
674
|
+
{post_inits_line}
|
689
675
|
super().__post_init__(**kwargs)
|
690
676
|
{post_inits_post_super_line}"""
|
691
677
|
)
|
692
|
-
if post_inits_line or
|
678
|
+
if post_inits_line or post_inits_post_super_line
|
693
679
|
else ""
|
694
680
|
)
|
695
681
|
|
@@ -0,0 +1 @@
|
|
1
|
+
__all__ = ["shacl_data_type", "shacl_ifabsent_processor"]
|
@@ -20,7 +20,7 @@ class ShaclDataType(DataType, Enum):
|
|
20
20
|
FLOAT = ("float", URIRef("http://www.w3.org/2001/XMLSchema#float"))
|
21
21
|
DOUBLE = ("double", URIRef("http://www.w3.org/2001/XMLSchema#double"))
|
22
22
|
URI = ("uri", URIRef("http://www.w3.org/2001/XMLSchema#anyURI"))
|
23
|
-
|
23
|
+
CURIE = ("curi", URIRef("http://www.w3.org/2001/XMLSchema#string"))
|
24
24
|
NCNAME = ("ncname", URIRef("http://www.w3.org/2001/XMLSchema#string"))
|
25
25
|
OBJECT_IDENTIFIER = ("objectidentifier", URIRef("http://www.w3.org/ns/shex#iri"))
|
26
26
|
NODE_IDENTIFIER = ("nodeidentifier", URIRef("http://www.w3.org/ns/shex#nonLiteral"))
|