linkml 1.7.2__tar.gz → 1.7.4__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.
Files changed (132) hide show
  1. {linkml-1.7.2 → linkml-1.7.4}/PKG-INFO +1 -2
  2. {linkml-1.7.2 → linkml-1.7.4}/linkml/__init__.py +7 -0
  3. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen.py +9 -9
  4. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/erdiagramgen.py +6 -6
  5. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/excelgen.py +3 -3
  6. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/golanggen.py +1 -1
  7. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/javagen.py +5 -5
  8. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/jsonldcontextgen.py +6 -5
  9. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/jsonschemagen.py +3 -3
  10. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/linkmlgen.py +3 -3
  11. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/markdowngen.py +2 -2
  12. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/oocodegen.py +4 -1
  13. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/owlgen.py +45 -26
  14. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/plantumlgen.py +4 -3
  15. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/protogen.py +2 -2
  16. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/pydanticgen.py +159 -13
  17. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/pythongen.py +5 -5
  18. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/rdfgen.py +2 -2
  19. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/shaclgen.py +2 -2
  20. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqltablegen.py +13 -9
  21. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/summarygen.py +2 -2
  22. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/yamlgen.py +2 -2
  23. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/yumlgen.py +5 -4
  24. {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/relmodel_transformer.py +5 -5
  25. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/converter.py +3 -2
  26. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/generator.py +4 -4
  27. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/sqlutils.py +2 -1
  28. {linkml-1.7.2 → linkml-1.7.4}/pyproject.toml +1 -5
  29. {linkml-1.7.2 → linkml-1.7.4}/setup.py +1 -1
  30. {linkml-1.7.2 → linkml-1.7.4}/LICENSE +0 -0
  31. {linkml-1.7.2 → linkml-1.7.4}/README.md +0 -0
  32. {linkml-1.7.2 → linkml-1.7.4}/linkml/_version.py +0 -0
  33. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/PythonGenNotes.md +0 -0
  34. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/README.md +0 -0
  35. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/__init__.py +0 -0
  36. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/common/__init__.py +0 -0
  37. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/common/type_designators.py +0 -0
  38. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/csvgen.py +0 -0
  39. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/class.md.jinja2 +0 -0
  40. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/class_diagram.md.jinja2 +0 -0
  41. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/common_metadata.md.jinja2 +0 -0
  42. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/enum.md.jinja2 +0 -0
  43. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/index.md.jinja2 +0 -0
  44. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/index.tex.jinja2 +0 -0
  45. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/schema.md.jinja2 +0 -0
  46. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/slot.md.jinja2 +0 -0
  47. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/subset.md.jinja2 +0 -0
  48. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/docgen/type.md.jinja2 +0 -0
  49. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/dotgen.py +0 -0
  50. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/golrgen.py +0 -0
  51. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/graphqlgen.py +0 -0
  52. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/javagen/example_template.java.jinja2 +0 -0
  53. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/javagen/java_record_template.jinja2 +0 -0
  54. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/jsonldgen.py +0 -0
  55. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/legacy/__init__.py +0 -0
  56. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/namespacegen.py +0 -0
  57. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/prefixmapgen.py +0 -0
  58. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/projectgen.py +0 -0
  59. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/shexgen.py +0 -0
  60. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sparqlgen.py +0 -0
  61. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemy/__init__.py +0 -0
  62. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemy/sqlalchemy_declarative_template.py +0 -0
  63. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemy/sqlalchemy_imperative_template.py +0 -0
  64. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlalchemygen.py +0 -0
  65. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sqlddlgen.py +0 -0
  66. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/sssomgen.py +0 -0
  67. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/string_template.md +0 -0
  68. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/terminusdbgen.py +0 -0
  69. {linkml-1.7.2 → linkml-1.7.4}/linkml/generators/typescriptgen.py +0 -0
  70. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/__init__.py +0 -0
  71. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/cli.py +0 -0
  72. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/.linkmllint.yaml +0 -0
  73. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/__init__.py +0 -0
  74. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/config.py +0 -0
  75. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/datamodel/config.yaml +0 -0
  76. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/default.yaml +0 -0
  77. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/config/recommended.yaml +0 -0
  78. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/__init__.py +0 -0
  79. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/formatter.py +0 -0
  80. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/json_formatter.py +0 -0
  81. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/markdown_formatter.py +0 -0
  82. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/terminal_formatter.py +0 -0
  83. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/formatters/tsv_formatter.py +0 -0
  84. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/linter.py +0 -0
  85. {linkml-1.7.2 → linkml-1.7.4}/linkml/linter/rules.py +0 -0
  86. {linkml-1.7.2 → linkml-1.7.4}/linkml/reporting/__init__.py +0 -0
  87. {linkml-1.7.2 → linkml-1.7.4}/linkml/reporting/model.py +0 -0
  88. {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/__init__.py +0 -0
  89. {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/logical_model_transformer.py +0 -0
  90. {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/model_transformer.py +0 -0
  91. {linkml-1.7.2 → linkml-1.7.4}/linkml/transformers/schema_renamer.py +0 -0
  92. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/__init__.py +0 -0
  93. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/cli_utils.py +0 -0
  94. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/datautils.py +0 -0
  95. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/datavalidator.py +0 -0
  96. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/execute_tutorial.py +0 -0
  97. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/helpers.py +0 -0
  98. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/ifabsent_functions.py +0 -0
  99. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/logictools.py +0 -0
  100. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/mergeutils.py +0 -0
  101. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/rawloader.py +0 -0
  102. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schema_builder.py +0 -0
  103. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schema_fixer.py +0 -0
  104. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schemaloader.py +0 -0
  105. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/schemasynopsis.py +0 -0
  106. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/typereferences.py +0 -0
  107. {linkml-1.7.2 → linkml-1.7.4}/linkml/utils/validation.py +0 -0
  108. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/__init__.py +0 -0
  109. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/cli.py +0 -0
  110. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/__init__.py +0 -0
  111. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/delimited_file_loader.py +0 -0
  112. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/json_loader.py +0 -0
  113. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/loader.py +0 -0
  114. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/passthrough_loader.py +0 -0
  115. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/loaders/yaml_loader.py +0 -0
  116. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/__init__.py +0 -0
  117. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/jsonschema_validation_plugin.py +0 -0
  118. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/pydantic_validation_plugin.py +0 -0
  119. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/recommended_slots_plugin.py +0 -0
  120. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/shacl_validation_plugin.py +0 -0
  121. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/plugins/validation_plugin.py +0 -0
  122. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/report.py +0 -0
  123. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/validation_context.py +0 -0
  124. {linkml-1.7.2 → linkml-1.7.4}/linkml/validator/validator.py +0 -0
  125. {linkml-1.7.2 → linkml-1.7.4}/linkml/validators/__init__.py +0 -0
  126. {linkml-1.7.2 → linkml-1.7.4}/linkml/validators/jsonschemavalidator.py +0 -0
  127. {linkml-1.7.2 → linkml-1.7.4}/linkml/validators/sparqlvalidator.py +0 -0
  128. {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/__init__.py +0 -0
  129. {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/datamodel/__init__.py +0 -0
  130. {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/datamodel/workspaces.py +0 -0
  131. {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/datamodel/workspaces.yaml +0 -0
  132. {linkml-1.7.2 → linkml-1.7.4}/linkml/workspaces/example_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: linkml
3
- Version: 1.7.2
3
+ Version: 1.7.4
4
4
  Summary: Linked Open Data Modeling Language
5
5
  Home-page: https://linkml.io/linkml/
6
6
  Keywords: schema,linked data,data modeling,rdf,owl,biolink
@@ -22,7 +22,6 @@ Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.8
23
23
  Classifier: Programming Language :: Python :: 3.9
24
24
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
- Provides-Extra: docs
26
25
  Requires-Dist: antlr4-python3-runtime (>=4.9.0,<4.10)
27
26
  Requires-Dist: click (>=7.0)
28
27
  Requires-Dist: graphviz (>=0.10.1)
@@ -71,3 +71,10 @@ BIOLINK_MODEL_URI = "https://w3id.org/biolink/biolink-model"
71
71
  BIOLINK_MODEL_PYTHON_LOC = "biolink.model"
72
72
 
73
73
  TurtleSerializer.roundtrip_prefixes = [""]
74
+
75
+ REQUESTS_TIMEOUT = 10
76
+ """
77
+ Time (in seconds) to wait before failing a network request
78
+
79
+ See: https://docs.python-requests.org/en/latest/user/advanced/#timeouts
80
+ """
@@ -126,7 +126,7 @@ class DocGenerator(Generator):
126
126
  # ObjectVars
127
127
  dialect: Optional[Union[DIALECT, str]] = None
128
128
  """markdown dialect (e.g MyST, Python)"""
129
- sort_by: str = field(default_factory=lambda: "name")
129
+ sort_by: str = "name"
130
130
  visit_all_class_slots = False
131
131
  template_mappings: Dict[str, str] = None
132
132
  directory: str = None
@@ -141,19 +141,19 @@ class DocGenerator(Generator):
141
141
  diagram_type: Optional[Union[DiagramType, str]] = None
142
142
  """style of diagram (ER, UML)"""
143
143
 
144
- include_top_level_diagram: bool = field(default_factory=lambda: False)
144
+ include_top_level_diagram: bool = False
145
145
  """Whether the index page should include a schema diagram"""
146
146
 
147
147
  example_directory: Optional[str] = None
148
148
  example_runner: ExampleRunner = field(default_factory=lambda: ExampleRunner())
149
149
 
150
- genmeta: bool = field(default_factory=lambda: False)
151
- gen_classvars: bool = field(default_factory=lambda: True)
152
- gen_slots: bool = field(default_factory=lambda: True)
153
- no_types_dir: bool = field(default_factory=lambda: False)
154
- use_slot_uris: bool = field(default_factory=lambda: False)
155
- use_class_uris: bool = field(default_factory=lambda: False)
156
- hierarchical_class_view: bool = field(default_factory=lambda: False)
150
+ genmeta: bool = False
151
+ gen_classvars: bool = True
152
+ gen_slots: bool = True
153
+ no_types_dir: bool = False
154
+ use_slot_uris: bool = False
155
+ use_class_uris: bool = False
156
+ hierarchical_class_view: bool = False
157
157
 
158
158
  def __post_init__(self):
159
159
  dialect = self.dialect
@@ -1,5 +1,5 @@
1
1
  import os
2
- from dataclasses import dataclass, field
2
+ from dataclasses import dataclass
3
3
  from enum import Enum
4
4
  from typing import List, Optional, Union
5
5
 
@@ -129,11 +129,11 @@ class ERDiagramGenerator(Generator):
129
129
  exclude_attributes: bool = False
130
130
  """If True, do not include attributes in entities"""
131
131
 
132
- genmeta: bool = field(default_factory=lambda: False)
133
- gen_classvars: bool = field(default_factory=lambda: True)
134
- gen_slots: bool = field(default_factory=lambda: True)
135
- no_types_dir: bool = field(default_factory=lambda: False)
136
- use_slot_uris: bool = field(default_factory=lambda: False)
132
+ genmeta: bool = False
133
+ gen_classvars: bool = True
134
+ gen_slots: bool = True
135
+ no_types_dir: bool = False
136
+ use_slot_uris: bool = False
137
137
 
138
138
  def __post_init__(self):
139
139
  self.schemaview = SchemaView(self.schema)
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from dataclasses import dataclass, field
2
+ from dataclasses import dataclass
3
3
  from pathlib import Path
4
4
  from typing import List
5
5
 
@@ -22,8 +22,8 @@ class ExcelGenerator(Generator):
22
22
  uses_schemaloader = False
23
23
  requires_metamodel = False
24
24
 
25
- split_workbook_by_class: bool = field(default_factory=lambda: False)
26
- include_mixins: bool = field(default_factory=lambda: False)
25
+ split_workbook_by_class: bool = False
26
+ include_mixins: bool = False
27
27
 
28
28
  def __post_init__(self) -> None:
29
29
  super().__post_init__()
@@ -160,7 +160,7 @@ class GolangGenerator(Generator):
160
160
  rc_name = self.name(rc)
161
161
  id_slot = self.get_identifier_or_key_slot(r)
162
162
  if slot.multivalued:
163
- if not id_slot or slot.inlined:
163
+ if not id_slot or slot.inlined or slot.inlined_as_list:
164
164
  if slot.inlined_as_list or not id_slot:
165
165
  return f"[]{rc_name}"
166
166
  else:
@@ -1,6 +1,6 @@
1
1
  import importlib.util
2
2
  import os
3
- from dataclasses import dataclass, field
3
+ from dataclasses import dataclass
4
4
  from typing import Optional
5
5
 
6
6
  import click
@@ -78,10 +78,10 @@ class JavaGenerator(OOCodeGenerator):
78
78
 
79
79
  template_file: Optional[str] = None
80
80
 
81
- gen_classvars: bool = field(default_factory=lambda: True)
82
- gen_slots: bool = field(default_factory=lambda: True)
83
- genmeta: bool = field(default_factory=lambda: False)
84
- emit_metadata: bool = field(default_factory=lambda: True)
81
+ gen_classvars: bool = True
82
+ gen_slots: bool = True
83
+ genmeta: bool = False
84
+ emit_metadata: bool = True
85
85
 
86
86
  def default_value_for_type(self, typ: str) -> str:
87
87
  return TYPE_DEFAULTS.get(typ, "null")
@@ -45,12 +45,12 @@ class ContextGenerator(Generator):
45
45
  default_ns: str = None
46
46
  context_body: Dict = field(default_factory=lambda: dict())
47
47
  slot_class_maps: Dict = field(default_factory=lambda: dict())
48
- emit_metadata: bool = field(default_factory=lambda: False)
49
- model: Optional[bool] = field(default_factory=lambda: True)
48
+ emit_metadata: bool = False
49
+ model: Optional[bool] = True
50
50
  base: Optional[str] = None
51
51
  output: Optional[str] = None
52
- prefixes: Optional[bool] = field(default_factory=lambda: True)
53
- flatprefixes: Optional[bool] = field(default_factory=lambda: False)
52
+ prefixes: Optional[bool] = True
53
+ flatprefixes: Optional[bool] = False
54
54
 
55
55
  def __post_init__(self) -> None:
56
56
  super().__post_init__()
@@ -150,7 +150,8 @@ class ContextGenerator(Generator):
150
150
  else:
151
151
  slot_def = {}
152
152
  if not slot.usage_slot_name:
153
- if slot.range in self.schema.classes:
153
+ any_of_ranges = [any_of_el.range for any_of_el in slot.any_of]
154
+ if slot.range in self.schema.classes or any(rng in self.schema.classes for rng in any_of_ranges):
154
155
  slot_def["@type"] = "@id"
155
156
  elif slot.range in self.schema.enums:
156
157
  slot_def["@context"] = ENUM_CONTEXT
@@ -2,7 +2,7 @@ import json
2
2
  import logging
3
3
  import os
4
4
  from copy import deepcopy
5
- from dataclasses import dataclass, field
5
+ from dataclasses import dataclass
6
6
  from typing import Any, Dict, List, Optional, Tuple, Union
7
7
 
8
8
  import click
@@ -179,7 +179,7 @@ class JsonSchemaGenerator(Generator):
179
179
  # @deprecated("Use top_class")
180
180
  topClass: Optional[str] = None
181
181
 
182
- not_closed: Optional[bool] = field(default_factory=lambda: True)
182
+ not_closed: Optional[bool] = True
183
183
  """If not closed, then an open-ended set of attributes can be instantiated for any object"""
184
184
 
185
185
  indent: int = 4
@@ -188,7 +188,7 @@ class JsonSchemaGenerator(Generator):
188
188
  top_class: Optional[Union[ClassDefinitionName, str]] = None # JSON object is one instance of this
189
189
  """Class instantiated by the root node of the document tree"""
190
190
 
191
- include_range_class_descendants: bool = field(default_factory=lambda: False)
191
+ include_range_class_descendants: bool = False
192
192
  """If set, use an open world assumption and allow the range of a slot to be any descendant of the declared range.
193
193
  Note that if the range of a slot has a type designator, descendants will always be included.
194
194
  """
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  import os
3
- from dataclasses import dataclass, field
3
+ from dataclasses import dataclass
4
4
  from typing import Union
5
5
 
6
6
  import click
@@ -30,8 +30,8 @@ class LinkmlGenerator(Generator):
30
30
  uses_schemaloader = False
31
31
  requires_metamodel = False
32
32
 
33
- materialize_attributes: bool = field(default_factory=lambda: False)
34
- materialize_patterns: bool = field(default_factory=lambda: False)
33
+ materialize_attributes: bool = False
34
+ materialize_patterns: bool = False
35
35
 
36
36
  def __post_init__(self):
37
37
  # TODO: consider moving up a level
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  from contextlib import redirect_stdout
3
- from dataclasses import dataclass, field
3
+ from dataclasses import dataclass
4
4
  from io import StringIO
5
5
  from typing import Any, Callable, Dict, List, Optional, Set, Union
6
6
 
@@ -47,7 +47,7 @@ class MarkdownGenerator(Generator):
47
47
  image_directory: Optional[str] = None
48
48
  classes: Set[ClassDefinitionName] = None
49
49
  image_dir: bool = False
50
- index_file: str = field(default_factory=lambda: "index.md")
50
+ index_file: str = "index.md"
51
51
  noimages: bool = False
52
52
  noyuml: bool = False
53
53
  no_types_dir: bool = False
@@ -141,7 +141,10 @@ class OOCodeGenerator(Generator):
141
141
  enum["description"] = enum_original.description
142
142
 
143
143
  for pv in enum_original.permissible_values.values():
144
- label = self.generate_enum_label(pv.text)
144
+ if pv.title:
145
+ label = self.generate_enum_label(pv.title)
146
+ else:
147
+ label = self.generate_enum_label(pv.text)
145
148
  val = {"label": label, "value": pv.text.replace('"', '\\"')}
146
149
  if hasattr(pv, "description"):
147
150
  val["description"] = pv.description
@@ -118,29 +118,29 @@ class OwlSchemaGenerator(Generator):
118
118
  """By default, use the linkml metadata profile,
119
119
  this allows for overrides."""
120
120
 
121
- metaclasses: bool = field(default_factory=lambda: True)
121
+ metaclasses: bool = True
122
122
  """if True, include OWL representations of ClassDefinition, SlotDefinition, etc. Introduces punning"""
123
123
 
124
- add_root_classes: bool = field(default_factory=lambda: False)
124
+ add_root_classes: bool = False
125
125
 
126
- add_ols_annotations: bool = field(default_factory=lambda: True)
126
+ add_ols_annotations: bool = True
127
127
  graph: Optional[Graph] = None
128
128
  """Mutable graph that is being built up during OWL generation."""
129
129
 
130
130
  top_value_uri: Optional[URIRef] = None
131
131
  """If metaclasses=True, then this property is used to connect object shadows to literals"""
132
132
 
133
- type_objects: bool = field(default_factory=lambda: True)
133
+ type_objects: bool = True
134
134
  """if True, represents types as classes (and thus all slots are object properties);
135
135
  typed object classes effectively shadow the main xsd literal types.
136
136
  The purpose of this is to allow a uniform ObjectProperty representation for all slots,
137
137
  without having to commit to being either Data or Object property (OWL-DL does not
138
138
  allow a property to be both."""
139
139
 
140
- assert_equivalent_classes: bool = field(default_factory=lambda: False)
140
+ assert_equivalent_classes: bool = False
141
141
  """If True, assert equivalence between definition_uris and class_uris"""
142
142
 
143
- use_native_uris: bool = field(default_factory=lambda: True)
143
+ use_native_uris: bool = True
144
144
  """If True, use the definition_uris, otherwise use class_uris."""
145
145
 
146
146
  mixins_as_expressions: bool = None
@@ -152,10 +152,10 @@ class OwlSchemaGenerator(Generator):
152
152
  node_owltypes: Mapping[Union[BNode, URIRef], Set[OWL_TYPE]] = field(default_factory=lambda: defaultdict(set))
153
153
  """rdfs:Datatype, owl:Thing"""
154
154
 
155
- simplify: bool = field(default_factory=lambda: True)
155
+ simplify: bool = True
156
156
  """Reduce complex expressions to simpler forms"""
157
157
 
158
- use_swrl: bool = field(default_factory=lambda: False)
158
+ use_swrl: bool = False
159
159
  """Use of SWRL is experimental"""
160
160
 
161
161
  target_profile: OWLProfile = field(default_factory=lambda: OWLProfile.dl)
@@ -378,8 +378,12 @@ class OwlSchemaGenerator(Generator):
378
378
  # rules yield OWL GCI subClassOf axioms
379
379
  for rule in cls.rules:
380
380
  pre_node = condition_to_bnode(rule.preconditions)
381
+ if not pre_node:
382
+ continue
381
383
  pre_node = self._intersection_of([pre_node, subject_expr])
382
384
  post_node = condition_to_bnode(rule.postconditions)
385
+ if not post_node:
386
+ continue
383
387
  self.graph.add((pre_node, RDFS.subClassOf, post_node))
384
388
  # classification rules yield OWL GCI subClassOf axioms
385
389
  for expr in cls.classification_rules:
@@ -433,15 +437,10 @@ class OwlSchemaGenerator(Generator):
433
437
  if slot.name in slot_map:
434
438
  for k, v in slot.__dict__.items():
435
439
  curr = slot_map[slot.name].get(k, None)
436
- # print(f"MERGE={slot.name}.{k} = {v} // CURR={curr}")
437
440
  if v and not curr:
438
441
  slot_map[slot.name][k] = v
439
- # print(f"OVERRIDE={slot.name}, k={k}, v={v}")
440
442
  else:
441
443
  slot_map[slot.name] = copy(slot.__dict__)
442
- # print(f"INIT={slot.name}, vals={slot_map[slot.name]}")
443
-
444
- # print(f"SN={slot.name}, vals={slot_map[slot.name]}")
445
444
  own_slots = [SlotDefinition(**v) for v in slot_map.values()]
446
445
  # sort by name
447
446
  own_slots.sort(key=lambda x: x.name)
@@ -462,6 +461,8 @@ class OwlSchemaGenerator(Generator):
462
461
  :param cls: LinkML class expression (anonymous if called recursively)
463
462
  :return: blank node representing the OWL expression
464
463
  """
464
+ if cls is None:
465
+ cls = AnonymousClassExpression()
465
466
  graph = self.graph
466
467
  sv = self.schemaview
467
468
  own_slots = self.get_own_slots(cls)
@@ -477,11 +478,13 @@ class OwlSchemaGenerator(Generator):
477
478
  graph.add((cls_uri, OWL.disjointUnionOf, listnode))
478
479
  else:
479
480
  sub_sub_exprs = []
480
- for i, x in enumerate(sub_exprs):
481
- rest = sub_exprs[0:i] + sub_exprs[i + 1 :]
482
- neg_expr = self._complement_of_union_of(rest)
483
- sub_sub_exprs.append(self._intersection_of([x, neg_expr]))
484
- sub_exprs.append(self._union_of(sub_sub_exprs))
481
+ for i, x in enumerate(cls.exactly_one_of):
482
+ rest = cls.exactly_one_of[0:i] + cls.exactly_one_of[i + 1 :]
483
+ neg_expr = self._complement_of_union_of([self.transform_class_expression(nx) for nx in rest])
484
+ pos_expr = self._intersection_of([self.transform_class_expression(x), neg_expr])
485
+ sub_sub_exprs.append(pos_expr)
486
+ owl_exprs.append(self._union_of(sub_sub_exprs))
487
+ # owl_exprs.extend(sub_exprs)
485
488
  if cls.all_of:
486
489
  owl_exprs.append(self._intersection_of([self.transform_class_expression(x) for x in cls.all_of]))
487
490
  if cls.none_of:
@@ -533,7 +536,8 @@ class OwlSchemaGenerator(Generator):
533
536
  graph.add((max_card_expr, OWL.onProperty, slot_uri))
534
537
  if slot.has_member:
535
538
  has_member_expr = self.transform_class_slot_expression(cls, slot.has_member, slot)
536
- owl_exprs.append(self._some_values_from(slot_uri, has_member_expr))
539
+ if has_member_expr:
540
+ owl_exprs.append(self._some_values_from(slot_uri, has_member_expr))
537
541
  return self._intersection_of(owl_exprs)
538
542
 
539
543
  def slot_node_owltypes(self, slot: Union[SlotDefinition, AnonymousSlotExpression]) -> Set[URIRef]:
@@ -558,7 +562,7 @@ class OwlSchemaGenerator(Generator):
558
562
  slot: Union[SlotDefinition, AnonymousSlotExpression],
559
563
  main_slot: SlotDefinition = None,
560
564
  owl_types: Set[OWL_TYPE] = None,
561
- ) -> Union[BNode, URIRef]:
565
+ ) -> Optional[Union[BNode, URIRef]]:
562
566
  """
563
567
  Take a ClassExpression and SlotExpression combination and transform to a node.
564
568
 
@@ -597,11 +601,19 @@ class OwlSchemaGenerator(Generator):
597
601
  )
598
602
  )
599
603
  if slot.exactly_one_of:
600
- owl_exprs.append(
601
- self._exactly_one_of(
602
- [self.transform_class_slot_expression(cls, x, main_slot, owl_types) for x in slot.exactly_one_of]
604
+ disj_exprs = []
605
+ for i, operand in enumerate(slot.exactly_one_of):
606
+ rest = slot.exactly_one_of[0:i] + slot.exactly_one_of[i + 1 :]
607
+ neg_expr = self._complement_of_union_of(
608
+ [self.transform_class_slot_expression(cls, x, main_slot, owl_types) for x in rest],
609
+ owl_types=owl_types,
603
610
  )
604
- )
611
+ pos_expr = self._intersection_of(
612
+ [self.transform_class_slot_expression(cls, operand, main_slot, owl_types), neg_expr],
613
+ owl_types=owl_types,
614
+ )
615
+ disj_exprs.append(pos_expr)
616
+ owl_exprs.append(self._union_of(disj_exprs, owl_types=owl_types))
605
617
  range = slot.range
606
618
  # if not range and not owl_exprs:
607
619
  # range = sv.schema.default_range
@@ -929,6 +941,10 @@ class OwlSchemaGenerator(Generator):
929
941
  triples.extend(graph.triples((obj, None, None)))
930
942
 
931
943
  def _some_values_from(self, property: URIRef, filler: Union[URIRef, BNode]) -> BNode:
944
+ if not property:
945
+ raise ValueError(f"Property is required, filler: {filler}")
946
+ if not filler:
947
+ raise ValueError(f"Filler is required, property: {property}")
932
948
  node = BNode()
933
949
  self.graph.add((node, RDF.type, OWL.Restriction))
934
950
  self.graph.add((node, OWL.onProperty, property))
@@ -970,11 +986,14 @@ class OwlSchemaGenerator(Generator):
970
986
  def _metaslot_uri(self, name: str) -> URIRef:
971
987
  return URIRef("https://w3id.org/linkml/" + name)
972
988
 
973
- def _complement_of_union_of(self, exprs: List[Union[BNode, URIRef]], **kwargs) -> Optional[Union[BNode, URIRef]]:
989
+ def _complement_of_union_of(
990
+ self, exprs: List[Union[BNode, URIRef]], owl_types: Set[OWL_TYPE] = None, **kwargs
991
+ ) -> Optional[Union[BNode, URIRef]]:
974
992
  if not exprs:
975
993
  raise ValueError("Must pass at least one")
976
994
  neg_expr = BNode()
977
- owl_types = self._get_owltypes(set(), exprs)
995
+ if not owl_types:
996
+ owl_types = self._get_owltypes(set(), exprs)
978
997
  complement_predicate = OWL.complementOf
979
998
  if len(owl_types) == 1:
980
999
  if RDFS.Literal in owl_types:
@@ -7,7 +7,7 @@ https://plantuml.com/
7
7
  import base64
8
8
  import os
9
9
  import zlib
10
- from dataclasses import dataclass, field
10
+ from dataclasses import dataclass
11
11
  from typing import Callable, List, Optional, Set, cast
12
12
 
13
13
  import click
@@ -19,6 +19,7 @@ from linkml_runtime.linkml_model.meta import (
19
19
  )
20
20
  from linkml_runtime.utils.formatutils import camelcase, underscore
21
21
 
22
+ from linkml import REQUESTS_TIMEOUT
22
23
  from linkml._version import __version__
23
24
  from linkml.utils.generator import Generator, shared_arguments
24
25
 
@@ -48,7 +49,7 @@ class PlantumlGenerator(Generator):
48
49
  classes: Set[ClassDefinitionName] = None
49
50
  directory: Optional[str] = None
50
51
  kroki_server: Optional[str] = "https://kroki.io"
51
- load_image: bool = field(default_factory=lambda: True)
52
+ load_image: bool = True
52
53
 
53
54
  def visit_schema(
54
55
  self,
@@ -101,7 +102,7 @@ class PlantumlGenerator(Generator):
101
102
  camelcase(sorted(classes)[0] if classes else self.schema.name) + file_suffix,
102
103
  )
103
104
  if load_image:
104
- resp = requests.get(plantuml_url, stream=True)
105
+ resp = requests.get(plantuml_url, stream=True, timeout=REQUESTS_TIMEOUT)
105
106
  if resp.ok:
106
107
  with open(self.output_file_name, "wb") as f:
107
108
  for chunk in resp.iter_content(chunk_size=2048):
@@ -1,5 +1,5 @@
1
1
  import os
2
- from dataclasses import dataclass, field
2
+ from dataclasses import dataclass
3
3
 
4
4
  import click
5
5
  from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
@@ -24,7 +24,7 @@ class ProtoGenerator(Generator):
24
24
  uses_schemaloader = True
25
25
 
26
26
  # ObjectVars
27
- relative_slot_num: int = field(default_factory=lambda: 0)
27
+ relative_slot_num: int = 0
28
28
 
29
29
  def __post_init__(self):
30
30
  super().__post_init__()