linkml 1.6.5__py3-none-any.whl → 1.6.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
  import logging
3
3
  import os
4
4
  from collections import defaultdict
5
+ from copy import copy
5
6
  from dataclasses import dataclass, field
6
7
  from enum import Enum, unique
7
8
  from typing import Any, List, Mapping, Optional, Set, Tuple, Union
@@ -403,6 +404,48 @@ class OwlSchemaGenerator(Generator):
403
404
  else:
404
405
  self.graph.add((subject_expr, RDFS.subClassOf, superclass_expr))
405
406
 
407
+ def get_own_slots(self, cls: Union[ClassDefinition, AnonymousClassExpression]) -> List[SlotDefinition]:
408
+ """
409
+ Get the slots that are defined on a class, excluding those that are inherited.
410
+
411
+ :param cls:
412
+ :return:
413
+ """
414
+ sv = self.schemaview
415
+ if isinstance(cls, ClassDefinition):
416
+ own_slots = (
417
+ list(cls.slot_usage.values()) + list(cls.attributes.values()) + list(cls.slot_conditions.values())
418
+ )
419
+ for slot_name in cls.slots:
420
+ # if slot_name not in cls.slot_usage:
421
+ slot = sv.get_slot(slot_name)
422
+ if slot:
423
+ own_slots.append(slot)
424
+ else:
425
+ logging.warning(f"Unknown top-level slot {slot_name}")
426
+ else:
427
+ own_slots = []
428
+ own_slots.extend(cls.slot_conditions.values())
429
+ # merge slots with the same name
430
+ slot_map = {}
431
+ for slot in own_slots:
432
+ if slot.name in slot_map:
433
+ for k, v in slot.__dict__.items():
434
+ curr = slot_map[slot.name].get(k, None)
435
+ # print(f"MERGE={slot.name}.{k} = {v} // CURR={curr}")
436
+ if v and not curr:
437
+ slot_map[slot.name][k] = v
438
+ # print(f"OVERRIDE={slot.name}, k={k}, v={v}")
439
+ else:
440
+ slot_map[slot.name] = copy(slot.__dict__)
441
+ # print(f"INIT={slot.name}, vals={slot_map[slot.name]}")
442
+
443
+ # print(f"SN={slot.name}, vals={slot_map[slot.name]}")
444
+ own_slots = [SlotDefinition(**v) for v in slot_map.values()]
445
+ # sort by name
446
+ own_slots.sort(key=lambda x: x.name)
447
+ return own_slots
448
+
406
449
  def transform_class_expression(
407
450
  self,
408
451
  cls: Union[ClassDefinition, AnonymousClassExpression],
@@ -420,20 +463,7 @@ class OwlSchemaGenerator(Generator):
420
463
  """
421
464
  graph = self.graph
422
465
  sv = self.schemaview
423
- if isinstance(cls, ClassDefinition):
424
- own_slots = (
425
- list(cls.slot_usage.values()) + list(cls.attributes.values()) + list(cls.slot_conditions.values())
426
- )
427
- for slot_name in cls.slots:
428
- if slot_name not in cls.slot_usage:
429
- slot = sv.get_slot(slot_name)
430
- if slot:
431
- own_slots.append(slot)
432
- else:
433
- own_slots = []
434
- own_slots.extend(cls.slot_conditions.values())
435
- # sort by name
436
- own_slots.sort(key=lambda x: x.name)
466
+ own_slots = self.get_own_slots(cls)
437
467
  owl_exprs = []
438
468
  if cls.any_of:
439
469
  owl_exprs.append(self._union_of([self.transform_class_expression(x) for x in cls.any_of]))
@@ -23,6 +23,7 @@ from linkml.generators.pythongen import PythonGenerator
23
23
  from linkml.generators.shaclgen import ShaclGenerator
24
24
  from linkml.generators.shexgen import ShExGenerator
25
25
  from linkml.generators.sqlddlgen import SQLDDLGenerator
26
+ from linkml.utils.cli_utils import log_level_option
26
27
  from linkml.utils.generator import Generator
27
28
 
28
29
  PATH_FSTRING = str
@@ -103,7 +104,7 @@ class ProjectGenerator:
103
104
  all_schemas = [schema_path]
104
105
  else:
105
106
  all_schemas = get_local_imports(schema_path, os.path.dirname(schema_path))
106
- print(f"ALL_SCHEMAS = {all_schemas}")
107
+ logging.debug(f"ALL_SCHEMAS = {all_schemas}")
107
108
  for gen_name, (gen_cls, gen_path_fmt, default_gen_args) in GEN_MAP.items():
108
109
  if config.includes is not None and config.includes != [] and gen_name not in config.includes:
109
110
  logging.info(f"Skipping {gen_name} as not in inclusion list: {config.includes}")
@@ -178,6 +179,7 @@ class ProjectGenerator:
178
179
  show_default=True,
179
180
  help="Merge imports into source file",
180
181
  )
182
+ @log_level_option
181
183
  @click.argument("yamlfile")
182
184
  @click.version_option(__version__, "-V", "--version")
183
185
  def cli(
@@ -221,7 +223,6 @@ def cli(
221
223
  top_class: Container
222
224
 
223
225
  """
224
- logging.basicConfig(level=logging.INFO)
225
226
  project_config = ProjectConfiguration()
226
227
  if config_file is not None:
227
228
  for k, v in yaml.safe_load(config_file).items():
@@ -44,14 +44,14 @@ from __future__ import annotations
44
44
  from datetime import datetime, date
45
45
  from enum import Enum
46
46
  from typing import List, Dict, Optional, Any, Union"""
47
- if pydantic_ver == 1:
47
+ if pydantic_ver == "1":
48
48
  template += """
49
- from pydantic import BaseModel as BaseModel, Field"""
50
- else:
49
+ from pydantic import BaseModel as BaseModel, Field, validator"""
50
+ elif pydantic_ver == "2":
51
51
  template += """
52
- from pydantic import BaseModel as BaseModel, ConfigDict, Field"""
53
-
52
+ from pydantic import BaseModel as BaseModel, ConfigDict, Field, field_validator"""
54
53
  template += """
54
+ import re
55
55
  import sys
56
56
  if sys.version_info >= (3, 8):
57
57
  from typing import Literal
@@ -134,7 +134,6 @@ class {{ c.name }}
134
134
  {%- endif -%}
135
135
  {%- if attr.title != None %}, title="{{attr.title}}"{% endif -%}
136
136
  {%- if attr.description %}, description=\"\"\"{{attr.description}}\"\"\"{% endif -%}
137
- {%- if attr.pattern %}, regex=\"{{attr.pattern}}\"{% endif -%}
138
137
  {%- if attr.equals_number != None %}, le={{attr.equals_number}}, ge={{attr.equals_number}}
139
138
  {%- else -%}
140
139
  {%- if attr.minimum_value != None %}, ge={{attr.minimum_value}}{% endif -%}
@@ -144,6 +143,21 @@ class {{ c.name }}
144
143
  {% else -%}
145
144
  None
146
145
  {% endfor %}
146
+ {% for attr in c.attributes.values() if c.attributes -%}
147
+ {%- if attr.pattern %}
148
+ @validator('{{attr.name}}', allow_reuse=True)
149
+ def pattern_{{attr.name}}(cls, v):
150
+ pattern=re.compile(r"{{attr.pattern}}")
151
+ if isinstance(v,list):
152
+ for element in v:
153
+ if not pattern.match(element):
154
+ raise ValueError(f"Invalid {{attr.name}} format: {element}")
155
+ elif isinstance(v,str):
156
+ if not pattern.match(v):
157
+ raise ValueError(f"Invalid {{attr.name}} format: {v}")
158
+ return v
159
+ {% endif -%}
160
+ {% endfor %}
147
161
  {% endfor %}
148
162
  """
149
163
  elif pydantic_ver == "2":
@@ -172,7 +186,6 @@ class {{ c.name }}
172
186
  {%- endif -%}
173
187
  {%- if attr.title != None %}, title="{{attr.title}}"{% endif -%}
174
188
  {%- if attr.description %}, description=\"\"\"{{attr.description}}\"\"\"{% endif -%}
175
- {%- if attr.pattern %}, pattern=\"{{attr.pattern}}\"{% endif -%}
176
189
  {%- if attr.equals_number != None %}, le={{attr.equals_number}}, ge={{attr.equals_number}}
177
190
  {%- else -%}
178
191
  {%- if attr.minimum_value != None %}, ge={{attr.minimum_value}}{% endif -%}
@@ -182,6 +195,21 @@ class {{ c.name }}
182
195
  {% else -%}
183
196
  None
184
197
  {% endfor %}
198
+ {% for attr in c.attributes.values() if c.attributes -%}
199
+ {%- if attr.pattern %}
200
+ @field_validator('{{attr.name}}')
201
+ def pattern_{{attr.name}}(cls, v):
202
+ pattern=re.compile(r"{{attr.pattern}}")
203
+ if isinstance(v,list):
204
+ for element in v:
205
+ if not pattern.match(element):
206
+ raise ValueError(f"Invalid {{attr.name}} format: {element}")
207
+ elif isinstance(v,str):
208
+ if not pattern.match(v):
209
+ raise ValueError(f"Invalid {{attr.name}} format: {v}")
210
+ return v
211
+ {% endif -%}
212
+ {% endfor %}
185
213
  {% endfor %}
186
214
  """
187
215
 
@@ -802,6 +802,11 @@ dataclasses._init_fn = dataclasses_init_fn_with_kwargs
802
802
  if self.is_class_unconstrained(self.schema.classes[slot.range]):
803
803
  return ""
804
804
 
805
+ if slot.range in self.schema.enums:
806
+ # Open enum
807
+ if not self.schema.enums[slot.range].permissible_values:
808
+ return ""
809
+
805
810
  aliased_slot_name = self.slot_name(slot.name) # Mangled name by which the slot is known in python
806
811
  _, _, base_type_name = self.class_reference_type(slot, cls)
807
812
 
@@ -0,0 +1,25 @@
1
+ import logging
2
+
3
+ import click
4
+
5
+ LOG_LEVEL_STRINGS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
6
+ DEFAULT_LOG_LEVEL: str = "WARNING"
7
+ DEFAULT_LOG_LEVEL_INT: int = logging.WARNING
8
+
9
+
10
+ def log_level_option(fn):
11
+ def callback(ctx, param, value):
12
+ log_level_string = value.upper()
13
+ log_level_int = getattr(logging, log_level_string, None)
14
+ if not isinstance(log_level_int, int):
15
+ raise ValueError(f"Invalid log level: {log_level_string}")
16
+ logging.basicConfig(level=log_level_int)
17
+
18
+ return click.option(
19
+ "--log_level",
20
+ type=click.Choice(LOG_LEVEL_STRINGS),
21
+ help="Logging level",
22
+ default=DEFAULT_LOG_LEVEL,
23
+ show_default=True,
24
+ callback=callback,
25
+ )(fn)
linkml/utils/generator.py CHANGED
@@ -51,13 +51,11 @@ from linkml_runtime.utils.formatutils import camelcase, underscore
51
51
  from linkml_runtime.utils.namespaces import Namespaces
52
52
 
53
53
  from linkml import LOCAL_METAMODEL_YAML_FILE
54
+ from linkml.utils.cli_utils import DEFAULT_LOG_LEVEL_INT, log_level_option
54
55
  from linkml.utils.mergeutils import alias_root
55
56
  from linkml.utils.schemaloader import SchemaLoader
56
57
  from linkml.utils.typereferences import References
57
58
 
58
- DEFAULT_LOG_LEVEL: str = "WARNING"
59
- DEFAULT_LOG_LEVEL_INT: int = logging.WARNING
60
-
61
59
 
62
60
  @lru_cache
63
61
  def _resolved_metamodel(mergeimports):
@@ -872,32 +870,16 @@ class Generator(metaclass=abc.ABCMeta):
872
870
 
873
871
 
874
872
  def shared_arguments(g: Type[Generator]) -> Callable[[Command], Command]:
875
- _LOG_LEVEL_STRINGS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
876
-
877
- def _log_level_string_to_int(log_level_string: str) -> int:
878
- log_level_string = log_level_string.upper()
879
- level = [e for e in log_level_string if e.startswith(log_level_string)]
880
- if not level:
881
- pass
882
- log_level_int = getattr(logging, log_level_string[0], logging.INFO)
883
- assert isinstance(log_level_int, int)
884
- return log_level_int
885
-
886
873
  def verbosity_callback(ctx, param, verbose):
887
874
  if verbose >= 2:
888
- logging.basicConfig(level=logging.DEBUG)
875
+ logging.basicConfig(level=logging.DEBUG, force=True)
889
876
  elif verbose == 1:
890
- logging.basicConfig(level=logging.INFO)
891
- else:
892
- logging.basicConfig(level=logging.WARNING)
877
+ logging.basicConfig(level=logging.INFO, force=True)
893
878
 
894
879
  def stacktrace_callback(ctx, param, stacktrace):
895
880
  if not stacktrace:
896
881
  sys.tracebacklimit = 0
897
882
 
898
- def log_level_callback(ctx, param, value):
899
- logging.basicConfig(level=_log_level_string_to_int(value))
900
-
901
883
  def decorator(f: Command) -> Command:
902
884
  f.params.append(Argument(("yamlfile",), type=click.Path(exists=True, dir_okay=False)))
903
885
  f.params.append(
@@ -926,21 +908,12 @@ def shared_arguments(g: Type[Generator]) -> Callable[[Command], Command]:
926
908
  )
927
909
  )
928
910
  f.params.append(Option(("--importmap", "-im"), type=click.File(), help="Import mapping file"))
929
- f.params.append(
930
- Option(
931
- ("--log_level",),
932
- type=click.Choice(_LOG_LEVEL_STRINGS),
933
- help="Logging level",
934
- default=DEFAULT_LOG_LEVEL,
935
- show_default=True,
936
- callback=log_level_callback,
937
- )
938
- )
911
+ log_level_option(f)
939
912
  f.params.append(
940
913
  Option(
941
914
  ("--verbose", "-v"),
942
915
  count=True,
943
- help="verbosity",
916
+ help="Verbosity. Takes precedence over --log_level.",
944
917
  callback=verbosity_callback,
945
918
  )
946
919
  )
@@ -3,7 +3,7 @@ import re
3
3
  from collections import defaultdict
4
4
  from copy import copy
5
5
  from dataclasses import dataclass
6
- from typing import Any, Callable, Dict, List, Union
6
+ from typing import Any, Callable, Dict, List, Optional, Union
7
7
 
8
8
  import click
9
9
  import yaml
@@ -319,15 +319,16 @@ class SchemaFixer:
319
319
  schema_dict: Dict[str, Any] = None,
320
320
  rules: Dict[str, Callable] = None,
321
321
  imports=False,
322
+ preserve_original_using: Optional[str] = None,
322
323
  ) -> Union[YAMLRoot, Dict]:
323
324
  """
324
325
  Changes element names to conform to naming conventions.
325
326
 
326
-
327
327
  :param schema: input schema
328
328
  :param schema_dict: if specified, the transformation will happen on this dictionary object
329
329
  :param rules: mappings between index slots and functions that normalize names
330
330
  :param imports: if True, all that imported modules are also fixed
331
+ :param preserve_original_using: if specified, the original name will be preserved in this slot
331
332
  :return:
332
333
  """
333
334
  if rules is None:
@@ -339,6 +340,7 @@ class SchemaFixer:
339
340
  }
340
341
  fixes = {}
341
342
  sv = SchemaView(schema)
343
+ preserved = []
342
344
  for n, e in sv.all_elements(imports=imports).items():
343
345
  if e.from_schema == "https://w3id.org/linkml/types":
344
346
  continue
@@ -348,9 +350,35 @@ class SchemaFixer:
348
350
  normalized = func(n)
349
351
  if normalized != n:
350
352
  fixes[n] = normalized
353
+ if preserve_original_using is not None:
354
+ preserved.append((typ, normalized, n))
355
+ # if preserve_original_using is not None:
356
+ # setattr(e, preserve_original_using, n)
357
+ # print(f"SETTING {typ} {e.name}.{preserve_original_using} = {n}")
351
358
  if schema_dict is not None:
352
359
  schema = schema_dict
353
- return yaml_rewrite(schema, fixes)
360
+ schema = yaml_rewrite(schema, fixes)
361
+ for typ, normalized, original in preserved:
362
+ pathmap = {
363
+ ClassDefinition.__name__: "classes",
364
+ TypeDefinition.__name__: "types",
365
+ SlotDefinition.__name__: "slots",
366
+ EnumDefinition.__name__: "enums",
367
+ }
368
+ if isinstance(schema, dict):
369
+ path = schema[pathmap[typ]]
370
+ if normalized not in path:
371
+ logger.warning(f"Cannot find {typ} {normalized} in {pathmap[typ]}")
372
+ continue
373
+ e = path[normalized]
374
+ if preserve_original_using not in e:
375
+ path[normalized][preserve_original_using] = original
376
+ else:
377
+ path = getattr(schema, pathmap[typ])
378
+ e = path[normalized]
379
+ if not getattr(e, preserve_original_using, None):
380
+ setattr(e, preserve_original_using, original)
381
+ return schema
354
382
 
355
383
 
356
384
  @click.group()
@@ -376,6 +404,13 @@ def main(verbose: int, quiet: bool):
376
404
  show_default=True,
377
405
  help="Apply fix to referenced elements from modules",
378
406
  )
407
+ @click.option(
408
+ "--preserve-original-using",
409
+ "-P",
410
+ default=None,
411
+ show_default=True,
412
+ help="If specified, original name will be preserved in this slot (e.g. title)",
413
+ )
379
414
  def fix_names(input_schema, **kwargs):
380
415
  """Fix element names to conform to naming conventions"""
381
416
  with open(input_schema) as f:
@@ -1,3 +1,4 @@
1
+ from functools import lru_cache
1
2
  from pathlib import Path
2
3
  from typing import Any, Iterator, List, Optional, TextIO, Union
3
4
 
@@ -95,7 +96,7 @@ class Validator:
95
96
  if not self._validation_plugins:
96
97
  return []
97
98
 
98
- context = ValidationContext(self._schema, target_class)
99
+ context = self._context(target_class)
99
100
 
100
101
  for plugin in self._validation_plugins:
101
102
  plugin.pre_process(context)
@@ -117,3 +118,7 @@ class Validator:
117
118
 
118
119
  for plugin in self._validation_plugins:
119
120
  plugin.post_process(context)
121
+
122
+ @lru_cache
123
+ def _context(self, target_class: Optional[str] = None) -> ValidationContext:
124
+ return ValidationContext(self._schema, target_class)
@@ -20,8 +20,7 @@ from linkml_runtime.linkml_model import ElementName
20
20
  from linkml_runtime.utils.formatutils import camelcase
21
21
 
22
22
  from linkml.generators.pythongen import PythonGenerator
23
- from linkml.utils.datavalidator import DataValidator
24
- from linkml.validators import JsonSchemaDataValidator
23
+ from linkml.validator import Validator, _get_default_validator
25
24
 
26
25
 
27
26
  @dataclass
@@ -77,7 +76,7 @@ class ExampleRunner:
77
76
  prefix_map: Optional[Mapping[str, str]] = None
78
77
  """Custom prefix map, for emitting RDF/turtle."""
79
78
 
80
- _validator: Optional[DataValidator] = None
79
+ _validator: Optional[Validator] = None
81
80
 
82
81
  expand_dicts: bool = None
83
82
  """If true, then expand all dicts prior to validation."""
@@ -101,14 +100,14 @@ class ExampleRunner:
101
100
  return self._python_module
102
101
 
103
102
  @property
104
- def validator(self) -> DataValidator:
103
+ def validator(self) -> Validator:
105
104
  """
106
105
  Get the current validator
107
106
 
108
107
  :return:
109
108
  """
110
109
  if self._validator is None:
111
- self._validator = JsonSchemaDataValidator(self.schemaview.schema)
110
+ self._validator = _get_default_validator(self.schemaview.schema)
112
111
  return self._validator
113
112
 
114
113
  def process_examples(self):
@@ -179,7 +178,11 @@ class ExampleRunner:
179
178
  summary.add(f"## {stem}", "### Input", "```yaml", f"{yaml.dump(input_dict)}", "```")
180
179
  success = True
181
180
  try:
182
- validator.validate_dict(input_dict, tc, closed=True)
181
+ report = validator.validate(input_dict, tc)
182
+ if report.results:
183
+ raise Exception(
184
+ "\n".join(f"[{result.severity.value}] {result.message}" for result in report.results)
185
+ )
183
186
  # json validation is incomplete: also try object instantiation
184
187
  self._load_from_dict(input_dict, target_class=tc)
185
188
  except Exception as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: linkml
3
- Version: 1.6.5
3
+ Version: 1.6.6
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
@@ -34,13 +34,13 @@ linkml/generators/linkmlgen.py,sha256=QhIPA1v2g_g5fien3ZKN-L6TkDk3t7puVFrcoEnwkw
34
34
  linkml/generators/markdowngen.py,sha256=ZPLahEPjWsrAsKq4CHbVDXeVd0n1NO-2STs068-g0Ac,32948
35
35
  linkml/generators/namespacegen.py,sha256=vVcIyM0zlKd7XRvtdzwTwHjG4Pg49801gy4FUmjJlqQ,6450
36
36
  linkml/generators/oocodegen.py,sha256=l-5zck_NNAUxJiApJrnDPkqxCv3b6v5s4hC_smelszU,7620
37
- linkml/generators/owlgen.py,sha256=6_OJufisaEetp9_bIrnKrQYvhxU8TiJhHZnSIacbEXw,51189
37
+ linkml/generators/owlgen.py,sha256=omOfL5oKHeQs-JARbGbTvydZ6DX4Bzyv5pukgW02kds,52419
38
38
  linkml/generators/plantumlgen.py,sha256=Vs__5x9ioiT4IBTbvZUpgT8MsYJ0amfBL64MB_nmQPc,14870
39
39
  linkml/generators/prefixmapgen.py,sha256=JJ7hgzuqKVfFZrbDV76Dk8dR2NHsmpp-eNUAspXkfwA,4626
40
- linkml/generators/projectgen.py,sha256=EVgS5bDzFTm3WAuMg3lC3rzdcaW-hgpq99qZA4nksSY,9544
40
+ linkml/generators/projectgen.py,sha256=g3JR2oXPM_QXhWUGukP9ts1P7tqxIeABaRdv130gbo4,9578
41
41
  linkml/generators/protogen.py,sha256=9YfxBZkQdBWwsUbstxEUR4xRWNuAKSfz9zXPhgIYePU,2328
42
- linkml/generators/pydanticgen.py,sha256=rH__R3Pt7TKQzG2DBo1R5OehQG3FaBMCjXBzZlAWMqw,23742
43
- linkml/generators/pythongen.py,sha256=7XNlOpScOOpxpo9Q_sasDOZFYaKifbXWQL-OKczpkfY,52327
42
+ linkml/generators/pydanticgen.py,sha256=RoFgX3-_8cx70Q3sUmSrZc0zTHbS0d55HgQp45U7fb4,24872
43
+ linkml/generators/pythongen.py,sha256=yGYlRJ4rNm2QQLFDjyuUnqCyKlzz-b3eSOhkSu8aCwI,52491
44
44
  linkml/generators/rdfgen.py,sha256=LxzYBaFEkV7rlf54nWv_6H6AGcWMRXwkaeVXq9VYEc8,2693
45
45
  linkml/generators/shaclgen.py,sha256=KxNmDZW2ciCuSqUhJ65TxLTjF8jME1FmN5SaWJCuW9k,8662
46
46
  linkml/generators/shexgen.py,sha256=Awtn5SyjS-TUcVCwMdT0F7hNO4K8VcSCYBaFru45Mwg,8994
@@ -82,18 +82,19 @@ linkml/transformers/model_transformer.py,sha256=tK_MpRDI-q2qfe8KHT6qJHP8ZruKjYx1
82
82
  linkml/transformers/relmodel_transformer.py,sha256=hRUVtH4gylDssOXoWvVxTetF9ESbITrAZOFu53b_Eg0,17836
83
83
  linkml/transformers/schema_renamer.py,sha256=Cr18TyktX64b5iFh5V6R_ILPVzXjbDYVDDZQyqFiAv8,5271
84
84
  linkml/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
+ linkml/utils/cli_utils.py,sha256=MdVbox1qr6kDUHUCWAmFhV-D6ebs_nn8vVwB8KDQfew,742
85
86
  linkml/utils/converter.py,sha256=rdhCI7Tsjddr3o1rVBfMq5gQubk_GE6fqlBBmyxI5_M,6270
86
87
  linkml/utils/datautils.py,sha256=2XWM9LBSVp8v3SwIZECrX3SjDUYzdnP-syjp6YdL89E,3734
87
88
  linkml/utils/datavalidator.py,sha256=kBdWaVi8IZT1bOwEJgJYx-wZAb_PTBObB9nHpYORfKA,472
88
89
  linkml/utils/execute_tutorial.py,sha256=T4kHTSyz3ItJGEUZxVjR-3yLVKnOr5Ix4NMGE47-IuE,6912
89
- linkml/utils/generator.py,sha256=dW9kfVL-7an0ieXR5HLe8bqOyEgDGAoIzdLOu_TFQhc,39101
90
+ linkml/utils/generator.py,sha256=WAlP_gfZfAZYNklsh8l4GtiWZ338kjLg7xpQAANgUNg,38217
90
91
  linkml/utils/helpers.py,sha256=yR8n4zFA5wPcYC7xzRuNF3wO16vG80v6j7DM3qTNmIc,447
91
92
  linkml/utils/ifabsent_functions.py,sha256=FZwceqwlq81lMPDsdNfSHhtzDXSf8F4cbbhRdnDzjss,5765
92
93
  linkml/utils/logictools.py,sha256=GSmBiobC49TcQjE08RtXEE3JwJEOV7eEREio25uJiFs,21184
93
94
  linkml/utils/mergeutils.py,sha256=QVm2iQB4v_L2rSvPBsPe9C865R03BgV3TzlPoTTTwWQ,9044
94
95
  linkml/utils/rawloader.py,sha256=QB7Rdvy4o4ZJEWBWa2_2xzz2TOh_6Oe4slvUn8IBVIc,4329
95
96
  linkml/utils/schema_builder.py,sha256=WLSit3J4lTifaFLLWTwjqIRiTru1pqvTIUuC1TrxS6Y,9902
96
- linkml/utils/schema_fixer.py,sha256=rjwJB5ukfrgc0Z-j3mKSNzRMkHPp_k_zFKaFNIPeIv8,15086
97
+ linkml/utils/schema_fixer.py,sha256=ajsxpwD4yMjDk1iDtoKJTsa34SIqGshWxlnSNXVZ52w,16745
97
98
  linkml/utils/schemaloader.py,sha256=bBSTqimMDTFH2FcKtRz99dKNJzV_myPsZSkIFp_6-A0,46421
98
99
  linkml/utils/schemasynopsis.py,sha256=6NKa89bkZfZQE9QM0St-6xQcrsHPkYmBgnnWnlgAcQ4,18455
99
100
  linkml/utils/sqlutils.py,sha256=86XeEbfY0Dk-EObw4q5-dxyzSeBtmIhjqqyDcR8ALS0,16591
@@ -114,7 +115,7 @@ linkml/validator/plugins/recommended_slots_plugin.py,sha256=kOdoYQyye47nLA7BjorV
114
115
  linkml/validator/plugins/validation_plugin.py,sha256=9SMHF8b2bgG9-8351e8bY676e0A4aEBJSXvMjMF5kXg,1548
115
116
  linkml/validator/report.py,sha256=kkkuh-IZF9--cO-2wGjwP3PDLvOcjjvC8AOlxXUIOAM,870
116
117
  linkml/validator/validation_context.py,sha256=MmOwLk4cF_Cy7fPdFK61Eti3c3dgzKSIu6r_PmkkoZs,2388
117
- linkml/validator/validator.py,sha256=jOSdYyC8QIm1GWmllM7Z1_GV-2VO3hwEwdF2AHE-DNY,5476
118
+ linkml/validator/validator.py,sha256=sdWbAOlnNYQWnZSEIuLpGQqH3W4cNq_8M_CdLtsNMH0,5648
118
119
  linkml/validators/__init__.py,sha256=43W3J5NPKhwa3ZFHLRYsJMocwQKWGYCF9Ki9r0ccGbc,202
119
120
  linkml/validators/jsonschemavalidator.py,sha256=_v0finzU2RGPC5xo0CylYge9XkY7oAigcly2SKLwFuI,7865
120
121
  linkml/validators/sparqlvalidator.py,sha256=JowuZ5KxmWkldgWIXAb8DJi7YCPm8x3it0QkgM4lSi0,4612
@@ -122,9 +123,9 @@ linkml/workspaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
122
123
  linkml/workspaces/datamodel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
124
  linkml/workspaces/datamodel/workspaces.py,sha256=4HdkqweGNfMPqnB1_Onc9DcTfkhoagTRcqruh08nRoI,14905
124
125
  linkml/workspaces/datamodel/workspaces.yaml,sha256=EjVrwPpeRZqJRjuGyyDRxxFzuv55SiLIXPBRUG6HStU,4233
125
- linkml/workspaces/example_runner.py,sha256=hblnsZVntuwFO4vqcwl_K5XH6jxb52xCtvdc7Sfq_Yc,11452
126
- linkml-1.6.5.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
127
- linkml-1.6.5.dist-info/LICENSE,sha256=kORMoywK6j9_iy0UvLR-a80P1Rvc9AOM4gsKlUNZABg,535
128
- linkml-1.6.5.dist-info/METADATA,sha256=dB0BnsijpuHie4nRiNeQ2N5mLQrr0pCu_6msKi2eWZo,3496
129
- linkml-1.6.5.dist-info/entry_points.txt,sha256=za8r49Z5gcz3rAYTZLbxw5EPZr1rGuxSe1uiRUpf8R0,2143
130
- linkml-1.6.5.dist-info/RECORD,,
126
+ linkml/workspaces/example_runner.py,sha256=uumXyPZ7xUJSZyRtjDP4TCCxgKSSOfebpufXc0_l0jY,11610
127
+ linkml-1.6.6.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
128
+ linkml-1.6.6.dist-info/LICENSE,sha256=kORMoywK6j9_iy0UvLR-a80P1Rvc9AOM4gsKlUNZABg,535
129
+ linkml-1.6.6.dist-info/entry_points.txt,sha256=za8r49Z5gcz3rAYTZLbxw5EPZr1rGuxSe1uiRUpf8R0,2143
130
+ linkml-1.6.6.dist-info/METADATA,sha256=TztvtOceZ4FBx8MPbnRdKJT2xLuWbBb_GOoA7hXLJsY,3496
131
+ linkml-1.6.6.dist-info/RECORD,,
File without changes