linkml 1.5.5__py3-none-any.whl → 1.5.7__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.
Files changed (81) hide show
  1. linkml/__init__.py +2 -6
  2. linkml/_version.py +1 -1
  3. linkml/generators/PythonGenNotes.md +4 -4
  4. linkml/generators/__init__.py +26 -5
  5. linkml/generators/common/type_designators.py +27 -22
  6. linkml/generators/csvgen.py +4 -10
  7. linkml/generators/docgen/class.md.jinja2 +7 -0
  8. linkml/generators/docgen/class_diagram.md.jinja2 +0 -6
  9. linkml/generators/docgen/subset.md.jinja2 +54 -13
  10. linkml/generators/docgen.py +94 -92
  11. linkml/generators/dotgen.py +5 -9
  12. linkml/generators/erdiagramgen.py +58 -53
  13. linkml/generators/excelgen.py +10 -16
  14. linkml/generators/golanggen.py +11 -21
  15. linkml/generators/golrgen.py +4 -13
  16. linkml/generators/graphqlgen.py +3 -11
  17. linkml/generators/javagen.py +8 -15
  18. linkml/generators/jsonldcontextgen.py +7 -36
  19. linkml/generators/jsonldgen.py +14 -12
  20. linkml/generators/jsonschemagen.py +183 -136
  21. linkml/generators/linkmlgen.py +1 -1
  22. linkml/generators/markdowngen.py +40 -89
  23. linkml/generators/namespacegen.py +1 -2
  24. linkml/generators/oocodegen.py +22 -25
  25. linkml/generators/owlgen.py +48 -49
  26. linkml/generators/prefixmapgen.py +6 -14
  27. linkml/generators/projectgen.py +7 -14
  28. linkml/generators/protogen.py +3 -5
  29. linkml/generators/pydanticgen.py +85 -73
  30. linkml/generators/pythongen.py +89 -157
  31. linkml/generators/rdfgen.py +5 -11
  32. linkml/generators/shaclgen.py +32 -18
  33. linkml/generators/shexgen.py +19 -24
  34. linkml/generators/sparqlgen.py +5 -13
  35. linkml/generators/sqlalchemy/__init__.py +3 -2
  36. linkml/generators/sqlalchemy/sqlalchemy_declarative_template.py +7 -7
  37. linkml/generators/sqlalchemy/sqlalchemy_imperative_template.py +3 -3
  38. linkml/generators/sqlalchemygen.py +29 -27
  39. linkml/generators/sqlddlgen.py +34 -26
  40. linkml/generators/sqltablegen.py +21 -21
  41. linkml/generators/sssomgen.py +11 -13
  42. linkml/generators/summarygen.py +2 -4
  43. linkml/generators/terminusdbgen.py +7 -19
  44. linkml/generators/typescriptgen.py +10 -18
  45. linkml/generators/yamlgen.py +0 -2
  46. linkml/generators/yumlgen.py +23 -71
  47. linkml/linter/cli.py +4 -11
  48. linkml/linter/config/datamodel/config.py +17 -47
  49. linkml/linter/linter.py +2 -4
  50. linkml/linter/rules.py +34 -48
  51. linkml/reporting/__init__.py +2 -0
  52. linkml/reporting/model.py +9 -24
  53. linkml/transformers/relmodel_transformer.py +20 -33
  54. linkml/transformers/schema_renamer.py +14 -10
  55. linkml/utils/converter.py +15 -15
  56. linkml/utils/datautils.py +9 -24
  57. linkml/utils/datavalidator.py +2 -2
  58. linkml/utils/execute_tutorial.py +10 -12
  59. linkml/utils/generator.py +74 -92
  60. linkml/utils/helpers.py +4 -2
  61. linkml/utils/ifabsent_functions.py +23 -15
  62. linkml/utils/mergeutils.py +19 -35
  63. linkml/utils/rawloader.py +2 -6
  64. linkml/utils/schema_builder.py +31 -19
  65. linkml/utils/schema_fixer.py +28 -18
  66. linkml/utils/schemaloader.py +44 -89
  67. linkml/utils/schemasynopsis.py +50 -73
  68. linkml/utils/sqlutils.py +40 -30
  69. linkml/utils/typereferences.py +9 -6
  70. linkml/utils/validation.py +4 -5
  71. linkml/validators/__init__.py +2 -0
  72. linkml/validators/jsonschemavalidator.py +104 -53
  73. linkml/validators/sparqlvalidator.py +5 -15
  74. linkml/workspaces/datamodel/workspaces.py +13 -30
  75. linkml/workspaces/example_runner.py +75 -68
  76. {linkml-1.5.5.dist-info → linkml-1.5.7.dist-info}/METADATA +2 -2
  77. linkml-1.5.7.dist-info/RECORD +109 -0
  78. linkml-1.5.5.dist-info/RECORD +0 -109
  79. {linkml-1.5.5.dist-info → linkml-1.5.7.dist-info}/LICENSE +0 -0
  80. {linkml-1.5.5.dist-info → linkml-1.5.7.dist-info}/WHEEL +0 -0
  81. {linkml-1.5.5.dist-info → linkml-1.5.7.dist-info}/entry_points.txt +0 -0
@@ -5,11 +5,10 @@ import os
5
5
  import sys
6
6
  from csv import DictWriter
7
7
  from dataclasses import dataclass, field
8
- from typing import Optional, TextIO, Union
8
+ from typing import Optional
9
9
 
10
10
  import click
11
- from linkml_runtime.linkml_model.meta import (ClassDefinition,
12
- SchemaDefinition, SlotDefinition)
11
+ from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
13
12
  from linkml_runtime.utils.formatutils import camelcase
14
13
 
15
14
  from linkml._version import __version__
@@ -18,7 +17,6 @@ from linkml.utils.generator import Generator, shared_arguments
18
17
 
19
18
  @dataclass
20
19
  class SummaryGenerator(Generator):
21
-
22
20
  # ClassVars
23
21
  generatorname = os.path.basename(__file__)
24
22
  generatorversion = "0.1.1"
@@ -1,11 +1,10 @@
1
1
  import json
2
2
  import os
3
3
  from dataclasses import dataclass
4
- from typing import TextIO, Union
4
+ from typing import List
5
5
 
6
6
  import click
7
- from linkml_runtime.linkml_model.meta import (ClassDefinition,
8
- SchemaDefinition, SlotDefinition)
7
+ from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
9
8
  from linkml_runtime.utils.formatutils import be, camelcase, underscore
10
9
  from terminusdb_client.woqlquery import WOQLQuery as WQ
11
10
 
@@ -35,6 +34,7 @@ XSD_Ok = {
35
34
  ]
36
35
  }
37
36
 
37
+
38
38
  @dataclass
39
39
  class TerminusdbGenerator(Generator):
40
40
  """
@@ -61,17 +61,12 @@ class TerminusdbGenerator(Generator):
61
61
  raw_additions: List = None
62
62
  clswq: str = None
63
63
 
64
-
65
64
  def visit_schema(self, inline: bool = False, **kwargs) -> None:
66
65
  self.classes = []
67
66
  self.raw_additions = []
68
67
 
69
68
  def end_schema(self, **_) -> None:
70
- print(
71
- json.dumps(
72
- WQ().woql_and(*self.classes, *self.raw_additions).to_dict(), indent=2
73
- )
74
- )
69
+ print(json.dumps(WQ().woql_and(*self.classes, *self.raw_additions).to_dict(), indent=2))
75
70
 
76
71
  def visit_class(self, cls: ClassDefinition) -> bool:
77
72
  self.clswq = (
@@ -86,8 +81,7 @@ class TerminusdbGenerator(Generator):
86
81
  self.clswq.abstract()
87
82
  if cls.broad_mappings:
88
83
  if any(
89
- str(self.namespaces.uri_for(m))
90
- == "http://terminusdb.com/schema/system#Document"
84
+ str(self.namespaces.uri_for(m)) == "http://terminusdb.com/schema/system#Document"
91
85
  for m in cls.broad_mappings
92
86
  ):
93
87
  self.clswq.parent("Document")
@@ -107,11 +101,7 @@ class TerminusdbGenerator(Generator):
107
101
  else:
108
102
  rng = "xsd:string"
109
103
 
110
- name = (
111
- f"{cls.name} {aliased_slot_name}"
112
- if slot.is_usage_slot
113
- else aliased_slot_name
114
- )
104
+ name = f"{cls.name} {aliased_slot_name}" if slot.is_usage_slot else aliased_slot_name
115
105
 
116
106
  # translate to terminusdb xsd builtins:
117
107
  if rng == "xsd:int":
@@ -127,9 +117,7 @@ class TerminusdbGenerator(Generator):
127
117
  f"Range {rng} is of type {type(rng)}."
128
118
  )
129
119
 
130
- self.clswq.property(
131
- underscore(name), rng, label=name, description=slot.description
132
- )
120
+ self.clswq.property(underscore(name), rng, label=name, description=slot.description)
133
121
  if not slot.multivalued:
134
122
  self.clswq.max(1)
135
123
  if slot.required:
@@ -1,22 +1,15 @@
1
1
  import logging
2
2
  import os
3
- from copy import deepcopy
4
3
  from dataclasses import dataclass
5
- from pathlib import Path
6
- from typing import (Callable, Dict, Iterator, List, Optional, Set, TextIO,
7
- Tuple, Union)
4
+ from typing import List, Optional
8
5
 
9
6
  import click
10
- from jinja2 import Environment, FileSystemLoader, Template
11
- from linkml_runtime.dumpers import yaml_dumper
7
+ from jinja2 import Template
12
8
  from linkml_runtime.linkml_model.meta import (
13
- Annotation, ClassDefinition,
14
- ClassDefinitionName, Definition,
15
- DefinitionName, Element,
16
- EnumDefinition, SchemaDefinition,
9
+ ClassDefinition,
10
+ ClassDefinitionName,
11
+ Element,
17
12
  SlotDefinition,
18
- SlotDefinitionName,
19
- TypeDefinition
20
13
  )
21
14
  from linkml_runtime.utils.formatutils import camelcase, underscore
22
15
  from linkml_runtime.utils.schemaview import SchemaView
@@ -55,7 +48,7 @@ export enum {{e.name}} {
55
48
  {% if pv.description -%}
56
49
  /** {{pv.description}} */
57
50
  {% endif -%}
58
- {{pv.label}} = "{{pv.value}}",
51
+ {{pv.label}} = "{{pv.value}}",
59
52
  {%- endfor %}
60
53
  };
61
54
  {% endfor %}
@@ -65,7 +58,7 @@ export enum {{e.name}} {
65
58
  /**
66
59
  * {{c.description}}
67
60
  */
68
- {%- endif -%}
61
+ {%- endif -%}
69
62
  {% set parents = gen.parents(c) %}
70
63
  export interface {{gen.name(c)}} {%- if parents %} extends {{parents|join(', ')}} {%- endif %} {
71
64
  {%- for sn in view.class_slots(c.name, direct=False) %}
@@ -137,9 +130,7 @@ class TypescriptGenerator(OOCodeGenerator):
137
130
  else:
138
131
  return None
139
132
 
140
- def get_identifier_or_key_slot(
141
- self, cn: ClassDefinitionName
142
- ) -> Optional[SlotDefinition]:
133
+ def get_identifier_or_key_slot(self, cn: ClassDefinitionName) -> Optional[SlotDefinition]:
143
134
  sv = self.schemaview
144
135
  id_slot = sv.get_identifier_slot(cn)
145
136
  if id_slot:
@@ -194,13 +185,14 @@ class TypescriptGenerator(OOCodeGenerator):
194
185
  def default_value_for_type(self, typ: str) -> str:
195
186
  pass
196
187
 
188
+
197
189
  @shared_arguments(TypescriptGenerator)
198
190
  @click.version_option(__version__, "-V", "--version")
199
191
  @click.command()
200
192
  def cli(yamlfile, **args):
201
193
  """Generate typescript interfaces and types
202
194
 
203
- See https://linkml.io/linkml-runtime.js
195
+ See https://github.com/linkml/linkml-runtime.js
204
196
  """
205
197
  gen = TypescriptGenerator(yamlfile, **args)
206
198
  print(gen.serialize())
@@ -3,10 +3,8 @@
3
3
  """
4
4
  import os
5
5
  from dataclasses import dataclass, field
6
- from typing import TextIO, Union
7
6
 
8
7
  import click
9
- from linkml_runtime.linkml_model.meta import SchemaDefinition
10
8
  from linkml_runtime.utils.yamlutils import as_yaml
11
9
 
12
10
  from linkml._version import __version__
@@ -3,20 +3,16 @@
3
3
  https://yuml.me/diagram/scruffy/class/samples
4
4
 
5
5
  """
6
- import logging
7
6
  import os
8
7
  from dataclasses import dataclass, field
9
- from typing import Callable, List, Optional, Set, TextIO, Union, cast
8
+ from typing import Callable, List, Optional, Set, cast
10
9
 
11
10
  import click
12
11
  import requests
13
- from linkml_runtime.linkml_model.meta import (ClassDefinition,
14
- ClassDefinitionName,
15
- SchemaDefinition, SlotDefinition)
12
+ from linkml_runtime.linkml_model.meta import ClassDefinition, ClassDefinitionName, SlotDefinition
16
13
  from linkml_runtime.utils.formatutils import camelcase, underscore
17
14
  from rdflib import Namespace
18
15
 
19
- from linkml._version import __version__
20
16
  from linkml.utils.generator import Generator, shared_arguments
21
17
 
22
18
  yuml_is_a = "^-"
@@ -41,34 +37,21 @@ class YumlGenerator(Generator):
41
37
  valid_formats = ["yuml", "png", "pdf", "jpg", "json", "svg"]
42
38
  visit_all_class_slots = False
43
39
 
44
- referenced: Optional[
45
- Set[ClassDefinitionName]
46
- ] = None # List of classes that have to be emitted
47
- generated: Optional[
48
- Set[ClassDefinitionName]
49
- ] = None # List of classes that have been emitted
50
- box_generated: Optional[
51
- Set[ClassDefinitionName]
52
- ] = None # Class boxes that have been emitted
40
+ referenced: Optional[Set[ClassDefinitionName]] = None # List of classes that have to be emitted
41
+ generated: Optional[Set[ClassDefinitionName]] = None # List of classes that have been emitted
42
+ box_generated: Optional[Set[ClassDefinitionName]] = None # Class boxes that have been emitted
53
43
  associations_generated: Optional[
54
44
  Set[ClassDefinitionName]
55
45
  ] = None # Classes with associations generated
56
- focus_classes: Optional[
57
- Set[ClassDefinitionName]
58
- ] = None # Classes to be completely filled
59
- gen_classes: Optional[
60
- Set[ClassDefinitionName]
61
- ] = None # Classes to be generated
62
- output_file_name: Optional[
63
- str
64
- ] = None # Location of output file if directory used
46
+ focus_classes: Optional[Set[ClassDefinitionName]] = None # Classes to be completely filled
47
+ gen_classes: Optional[Set[ClassDefinitionName]] = None # Classes to be generated
48
+ output_file_name: Optional[str] = None # Location of output file if directory used
65
49
 
66
50
  classes: Set[ClassDefinitionName] = None
67
51
  directory: Optional[str] = None
68
52
  diagram_name: Optional[str] = None
69
53
  load_image: bool = field(default_factory=lambda: True)
70
54
 
71
-
72
55
  def visit_schema(
73
56
  self,
74
57
  classes: Set[ClassDefinitionName] = None,
@@ -94,22 +77,16 @@ class YumlGenerator(Generator):
94
77
  self.generated = set()
95
78
  yumlclassdef: List[str] = []
96
79
  while self.referenced.difference(self.generated):
97
- cn = sorted(list(self.referenced.difference(self.generated)), reverse=True)[
98
- 0
99
- ]
80
+ cn = sorted(list(self.referenced.difference(self.generated)), reverse=True)[0]
100
81
  self.generated.add(cn)
101
- assocs = self.class_associations(
102
- ClassDefinitionName(cn), cn in self.referenced
103
- )
82
+ assocs = self.class_associations(ClassDefinitionName(cn), cn in self.referenced)
104
83
  if assocs:
105
84
  yumlclassdef.append(assocs)
106
85
  else:
107
86
  yumlclassdef.append(self.class_box(ClassDefinitionName(cn)))
108
87
 
109
88
  file_suffix = ".svg" if self.format == "yuml" else "." + self.format
110
- file_name = diagram_name or camelcase(
111
- sorted(classes)[0] if classes else self.schema.name
112
- )
89
+ file_name = diagram_name or camelcase(sorted(classes)[0] if classes else self.schema.name)
113
90
  if directory:
114
91
  self.output_file_name = os.path.join(
115
92
  directory,
@@ -118,7 +95,7 @@ class YumlGenerator(Generator):
118
95
  if load_image:
119
96
  payload = "dsl_text=" + (",".join(yumlclassdef))
120
97
  payload = payload.replace("%3F", "?").replace("%2B", "+")
121
- url = f"https://yuml.me/diagram/plain/class/"
98
+ url = "https://yuml.me/diagram/plain/class/"
122
99
  resp = requests.post(url, data=payload)
123
100
  if resp.ok:
124
101
  filename = resp.text.strip().replace(".svg", file_suffix)
@@ -139,9 +116,7 @@ class YumlGenerator(Generator):
139
116
  @return:
140
117
  """
141
118
  slot_defs: List[str] = []
142
- if cn not in self.box_generated and (
143
- not self.focus_classes or cn in self.focus_classes
144
- ):
119
+ if cn not in self.box_generated and (not self.focus_classes or cn in self.focus_classes):
145
120
  cls = self.schema.classes[cn]
146
121
  for slot in self.filtered_cls_slots(
147
122
  cn, all_slots=True, filtr=lambda s: s.range not in self.schema.classes
@@ -157,13 +132,9 @@ class YumlGenerator(Generator):
157
132
  )
158
133
  self.box_generated.add(cn)
159
134
  self.referenced.add(cn)
160
- return (
161
- "[" + camelcase(cn) + ("|" + ";".join(slot_defs) if slot_defs else "") + "]"
162
- )
135
+ return "[" + camelcase(cn) + ("|" + ";".join(slot_defs) if slot_defs else "") + "]"
163
136
 
164
- def class_associations(
165
- self, cn: ClassDefinitionName, must_render: bool = False
166
- ) -> str:
137
+ def class_associations(self, cn: ClassDefinitionName, must_render: bool = False) -> str:
167
138
  """Emit all associations for a focus class. If none are specified, all classes are generated
168
139
 
169
140
  @param cn: Name of class to be emitted
@@ -184,10 +155,7 @@ class YumlGenerator(Generator):
184
155
  cn, False, lambda s: s.range in self.schema.classes
185
156
  )[::-1]:
186
157
  # Swap the two boxes because, in the case of self reference, the last definition wins
187
- if (
188
- not slot.range in self.associations_generated
189
- and cn in slot.domain_of
190
- ):
158
+ if slot.range not in self.associations_generated and cn in slot.domain_of:
191
159
  rhs = self.class_box(cn)
192
160
  lhs = self.class_box(cast(ClassDefinitionName, slot.range))
193
161
  assocs.append(
@@ -205,10 +173,7 @@ class YumlGenerator(Generator):
205
173
  slot = self.schema.slots[slotname]
206
174
  # Don't do self references twice
207
175
  # Also, slot must be owned by the class
208
- if (
209
- cls.name not in slot.domain_of
210
- and cls.name not in self.associations_generated
211
- ):
176
+ if cls.name not in slot.domain_of and cls.name not in self.associations_generated:
212
177
  for dom in [self.schema.classes[dof] for dof in slot.domain_of]:
213
178
  assocs.append(
214
179
  self.class_box(dom.name)
@@ -226,20 +191,14 @@ class YumlGenerator(Generator):
226
191
 
227
192
  # Classes that use the class as a mixin
228
193
  if cls.name in self.synopsis.mixinrefs:
229
- for mixin in sorted(
230
- self.synopsis.mixinrefs[cls.name].classrefs, reverse=True
231
- ):
194
+ for mixin in sorted(self.synopsis.mixinrefs[cls.name].classrefs, reverse=True):
232
195
  assocs.append(
233
- self.class_box(ClassDefinitionName(mixin))
234
- + yuml_uses
235
- + self.class_box(cn)
196
+ self.class_box(ClassDefinitionName(mixin)) + yuml_uses + self.class_box(cn)
236
197
  )
237
198
 
238
199
  # Classes that inject information
239
200
  if cn in self.synopsis.applytos.classrefs:
240
- for injector in sorted(
241
- self.synopsis.applytorefs[cn].classrefs, reverse=True
242
- ):
201
+ for injector in sorted(self.synopsis.applytorefs[cn].classrefs, reverse=True):
243
202
  assocs.append(
244
203
  self.class_box(cn)
245
204
  + yuml_injected
@@ -249,9 +208,7 @@ class YumlGenerator(Generator):
249
208
 
250
209
  # Children
251
210
  if cn in self.synopsis.isarefs:
252
- for is_a_cls in sorted(
253
- self.synopsis.isarefs[cn].classrefs, reverse=True
254
- ):
211
+ for is_a_cls in sorted(self.synopsis.isarefs[cn].classrefs, reverse=True):
255
212
  assocs.append(
256
213
  self.class_box(cn)
257
214
  + yuml_is_a
@@ -280,7 +237,7 @@ class YumlGenerator(Generator):
280
237
  self,
281
238
  cn: ClassDefinitionName,
282
239
  all_slots: bool = True,
283
- filtr: Callable[[SlotDefinition], bool] = None,
240
+ filtr: Callable[[SlotDefinition], bool] = lambda: True,
284
241
  ) -> List[SlotDefinition]:
285
242
  """Return the set of slots associated with the class that meet the filter criteria. Slots will be returned
286
243
  in defining order, with class slots returned last
@@ -290,9 +247,6 @@ class YumlGenerator(Generator):
290
247
  @param filtr: Slot filter predicate
291
248
  @return: List of slot definitions
292
249
  """
293
- if filtr is None:
294
- filtr = lambda x: True
295
-
296
250
  rval = []
297
251
  cls = self.schema.classes[cn]
298
252
  cls_slots = self.all_slots(cls, cls_slots_first=True)
@@ -325,9 +279,7 @@ class YumlGenerator(Generator):
325
279
  for a in sorted(self.synopsis.applytorefs[cls.name].classrefs)
326
280
  ]
327
281
  ]
328
- return pk + (
329
- "(a)" if injected else "(m)" if mixin else "(i)" if inherited else ""
330
- )
282
+ return pk + ("(a)" if injected else "(m)" if mixin else "(i)" if inherited else "")
331
283
 
332
284
 
333
285
  @shared_arguments(YumlGenerator)
linkml/linter/cli.py CHANGED
@@ -9,8 +9,7 @@ import yaml
9
9
  from linkml._version import __version__
10
10
 
11
11
  from .config.datamodel.config import RuleLevel
12
- from .formatters import (JsonFormatter, MarkdownFormatter, TerminalFormatter,
13
- TsvFormatter)
12
+ from .formatters import JsonFormatter, MarkdownFormatter, TerminalFormatter, TsvFormatter
14
13
  from .linter import Linter
15
14
 
16
15
  YAML_SUFFIXES = [".yml", ".yaml"]
@@ -35,9 +34,7 @@ def get_yaml_files(root: Path) -> Iterable[str]:
35
34
  @click.command()
36
35
  @click.argument(
37
36
  "schema",
38
- type=click.Path(
39
- exists=True, dir_okay=True, file_okay=True, resolve_path=True, path_type=Path
40
- ),
37
+ type=click.Path(exists=True, dir_okay=True, file_okay=True, resolve_path=True, path_type=Path),
41
38
  )
42
39
  @click.option(
43
40
  "-c",
@@ -66,9 +63,7 @@ def get_yaml_files(root: Path) -> Iterable[str]:
66
63
  help="Validate the schema against the LinkML Metamodel and then exit without checking linter rules.",
67
64
  )
68
65
  @click.option("-v", "--verbose", is_flag=True)
69
- @click.option(
70
- "-o", "--output", type=click.File("w"), default="-", help="Report file name."
71
- )
66
+ @click.option("-o", "--output", type=click.File("w"), default="-", help="Report file name.")
72
67
  @click.option(
73
68
  "--ignore-warnings",
74
69
  is_flag=True,
@@ -131,9 +126,7 @@ def main(
131
126
  formatter.start_report()
132
127
  for path in get_yaml_files(schema):
133
128
  formatter.start_schema(path)
134
- report = linter.lint(
135
- path, fix=fix, validate_schema=validate, validate_only=validate_only
136
- )
129
+ report = linter.lint(path, fix=fix, validate_schema=validate, validate_only=validate_only)
137
130
  for problem in report:
138
131
  if str(problem.level) is RuleLevel.error.text:
139
132
  error_count += 1
@@ -7,26 +7,18 @@
7
7
  # license: https://creativecommons.org/publicdomain/zero/1.0/
8
8
 
9
9
  import dataclasses
10
- import re
11
- import sys
12
10
  from dataclasses import dataclass
13
11
  from typing import Any, ClassVar, Dict, List, Optional, Union
14
12
 
15
- from jsonasobj2 import JsonObj, as_dict
16
- from linkml_runtime.linkml_model.meta import (EnumDefinition, PermissibleValue,
17
- PvFormulaOptions)
18
- from linkml_runtime.linkml_model.types import Boolean, String
13
+ from jsonasobj2 import as_dict
14
+ from linkml_runtime.linkml_model.meta import EnumDefinition, PermissibleValue
19
15
  from linkml_runtime.utils.curienamespace import CurieNamespace
20
- from linkml_runtime.utils.dataclass_extensions_376 import \
21
- dataclasses_init_fn_with_kwargs
16
+ from linkml_runtime.utils.dataclass_extensions_376 import dataclasses_init_fn_with_kwargs
22
17
  from linkml_runtime.utils.enumerations import EnumDefinitionImpl
23
- from linkml_runtime.utils.formatutils import camelcase, sfx, underscore
24
- from linkml_runtime.utils.metamodelcore import (Bool, bnode, empty_dict,
25
- empty_list)
18
+ from linkml_runtime.utils.metamodelcore import Bool, empty_list
26
19
  from linkml_runtime.utils.slot import Slot
27
- from linkml_runtime.utils.yamlutils import (YAMLRoot, extended_float,
28
- extended_int, extended_str)
29
- from rdflib import Namespace, URIRef
20
+ from linkml_runtime.utils.yamlutils import YAMLRoot
21
+ from rdflib import URIRef
30
22
 
31
23
  metamodel_version = "1.7.0"
32
24
  version = None
@@ -82,9 +74,7 @@ class Rules(YAMLRoot):
82
74
  class_model_uri: ClassVar[URIRef] = LINTCFG.Rules
83
75
 
84
76
  no_empty_title: Optional[Union[dict, "RuleConfig"]] = None
85
- permissible_values_format: Optional[
86
- Union[dict, "PermissibleValuesFormatRuleConfig"]
87
- ] = None
77
+ permissible_values_format: Optional[Union[dict, "PermissibleValuesFormatRuleConfig"]] = None
88
78
  tree_root_class: Optional[Union[dict, "TreeRootClassRuleConfig"]] = None
89
79
  recommended: Optional[Union[dict, "RecommendedRuleConfig"]] = None
90
80
  no_xsd_int_type: Optional[Union[dict, "RuleConfig"]] = None
@@ -93,9 +83,7 @@ class Rules(YAMLRoot):
93
83
  canonical_prefixes: Optional[Union[dict, "CanonicalPrefixesConfig"]] = None
94
84
 
95
85
  def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
96
- if self.no_empty_title is not None and not isinstance(
97
- self.no_empty_title, RuleConfig
98
- ):
86
+ if self.no_empty_title is not None and not isinstance(self.no_empty_title, RuleConfig):
99
87
  self.no_empty_title = RuleConfig(**as_dict(self.no_empty_title))
100
88
 
101
89
  if self.permissible_values_format is not None and not isinstance(
@@ -108,26 +96,18 @@ class Rules(YAMLRoot):
108
96
  if self.tree_root_class is not None and not isinstance(
109
97
  self.tree_root_class, TreeRootClassRuleConfig
110
98
  ):
111
- self.tree_root_class = TreeRootClassRuleConfig(
112
- **as_dict(self.tree_root_class)
113
- )
99
+ self.tree_root_class = TreeRootClassRuleConfig(**as_dict(self.tree_root_class))
114
100
 
115
- if self.recommended is not None and not isinstance(
116
- self.recommended, RecommendedRuleConfig
117
- ):
101
+ if self.recommended is not None and not isinstance(self.recommended, RecommendedRuleConfig):
118
102
  self.recommended = RecommendedRuleConfig(**as_dict(self.recommended))
119
103
 
120
- if self.no_xsd_int_type is not None and not isinstance(
121
- self.no_xsd_int_type, RuleConfig
122
- ):
104
+ if self.no_xsd_int_type is not None and not isinstance(self.no_xsd_int_type, RuleConfig):
123
105
  self.no_xsd_int_type = RuleConfig(**as_dict(self.no_xsd_int_type))
124
106
 
125
107
  if self.no_invalid_slot_usage is not None and not isinstance(
126
108
  self.no_invalid_slot_usage, RuleConfig
127
109
  ):
128
- self.no_invalid_slot_usage = RuleConfig(
129
- **as_dict(self.no_invalid_slot_usage)
130
- )
110
+ self.no_invalid_slot_usage = RuleConfig(**as_dict(self.no_invalid_slot_usage))
131
111
 
132
112
  if self.standard_naming is not None and not isinstance(
133
113
  self.standard_naming, StandardNamingConfig
@@ -137,9 +117,7 @@ class Rules(YAMLRoot):
137
117
  if self.canonical_prefixes is not None and not isinstance(
138
118
  self.canonical_prefixes, CanonicalPrefixesConfig
139
119
  ):
140
- self.canonical_prefixes = CanonicalPrefixesConfig(
141
- **as_dict(self.canonical_prefixes)
142
- )
120
+ self.canonical_prefixes = CanonicalPrefixesConfig(**as_dict(self.canonical_prefixes))
143
121
 
144
122
  super().__post_init__(**kwargs)
145
123
 
@@ -209,9 +187,7 @@ class TreeRootClassRuleConfig(RuleConfig):
209
187
  validate_existing_class_name: Optional[Union[bool, Bool]] = None
210
188
 
211
189
  def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
212
- if self.root_class_name is not None and not isinstance(
213
- self.root_class_name, str
214
- ):
190
+ if self.root_class_name is not None and not isinstance(self.root_class_name, str):
215
191
  self.root_class_name = str(self.root_class_name)
216
192
 
217
193
  if self.validate_existing_class_name is not None and not isinstance(
@@ -271,9 +247,7 @@ class StandardNamingConfig(RuleConfig):
271
247
  if self.permissible_values_upper_case is not None and not isinstance(
272
248
  self.permissible_values_upper_case, Bool
273
249
  ):
274
- self.permissible_values_upper_case = Bool(
275
- self.permissible_values_upper_case
276
- )
250
+ self.permissible_values_upper_case = Bool(self.permissible_values_upper_case)
277
251
 
278
252
  super().__post_init__(**kwargs)
279
253
 
@@ -297,9 +271,7 @@ class CanonicalPrefixesConfig(RuleConfig):
297
271
  def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
298
272
  if not isinstance(self.prefixmaps_contexts, list):
299
273
  self.prefixmaps_contexts = (
300
- [self.prefixmaps_contexts]
301
- if self.prefixmaps_contexts is not None
302
- else []
274
+ [self.prefixmaps_contexts] if self.prefixmaps_contexts is not None else []
303
275
  )
304
276
  self.prefixmaps_contexts = [
305
277
  v if isinstance(v, str) else str(v) for v in self.prefixmaps_contexts
@@ -329,9 +301,7 @@ class RuleLevel(EnumDefinitionImpl):
329
301
  The permissible values for the `level` option of all rules
330
302
  """
331
303
 
332
- disabled = PermissibleValue(
333
- text="disabled", description="The rule will not be checked"
334
- )
304
+ disabled = PermissibleValue(text="disabled", description="The rule will not be checked")
335
305
  warning = PermissibleValue(
336
306
  text="warning",
337
307
  description="A violation of a rule at this level is a minor issue that should be fixed",
linkml/linter/linter.py CHANGED
@@ -70,9 +70,7 @@ class Linter:
70
70
  default_config = deepcopy(get_named_config("default"))
71
71
  merged_config = config
72
72
  if config.get("extends") == ExtendableConfigs.recommended.text:
73
- recommended_config = deepcopy(
74
- get_named_config(ExtendableConfigs.recommended.text)
75
- )
73
+ recommended_config = deepcopy(get_named_config(ExtendableConfigs.recommended.text))
76
74
  merged_config = merge_configs(recommended_config, merged_config)
77
75
  merged_config = merge_configs(default_config, merged_config)
78
76
  self.config = Config(**merged_config)
@@ -119,7 +117,7 @@ class Linter:
119
117
 
120
118
  try:
121
119
  schema_view = SchemaView(schema)
122
- except:
120
+ except Exception:
123
121
  if not validate_schema:
124
122
  yield LinterProblem(
125
123
  message="File is not a valid LinkML schema. Use --validate for more details.",