Skip to content

Commit b6ab7a2

Browse files
Improve class uri handling
This commit improves handling full class uris in three ways: - It preserves the `$base` field in a `_base` global variable to allow using it in the generated Python parser - It relies on the `_base` variable to distinguish between base classes and namespaced extensions while saving a document - It removes the `class_uri` field and retrieves the full class uri directly from the `rvocab` data structure
1 parent c03995e commit b6ab7a2

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

schema_salad/codegen.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def codegen(
8484
gen.parse(j)
8585
return
8686
gen = PythonCodeGen(
87-
dest, copyright=copyright, parser_info=info, salad_version=salad_version
87+
base, dest, copyright=copyright, parser_info=info, salad_version=salad_version
8888
)
8989

9090
elif lang == "java":

schema_salad/metaschema.py

+1
Original file line numberDiff line numberDiff line change
@@ -7267,6 +7267,7 @@ def save(
72677267
)
72687268

72697269

7270+
_base = "https://w3id.org/cwl/salad#"
72707271
_vocab = {
72717272
"Any": "https://w3id.org/cwl/salad#Any",
72727273
"ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",

schema_salad/python_codegen.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,14 @@ class PythonCodeGen(CodeGenBase):
7070

7171
def __init__(
7272
self,
73+
base: str,
7374
out: IO[str],
7475
copyright: Optional[str],
7576
parser_info: str,
7677
salad_version: str,
7778
) -> None:
7879
super().__init__()
80+
self.base_uri = base
7981
self.out = out
8082
self.current_class_is_abstract = False
8183
self.serializer = StringIO()
@@ -143,7 +145,6 @@ def begin_class(
143145
idfield: str,
144146
optional_fields: set[str],
145147
) -> None:
146-
class_uri = classname
147148
classname = self.safe_name(classname)
148149

149150
if extends:
@@ -166,12 +167,7 @@ def begin_class(
166167

167168
idfield_safe_name = self.safe_name(idfield) if idfield != "" else None
168169
if idfield_safe_name is not None:
169-
self.out.write(f" {idfield_safe_name}: str\n")
170-
if "class" not in field_names:
171-
self.out.write("\n")
172-
173-
if "class" in field_names:
174-
self.out.write(f' class_uri = "{class_uri}"\n\n')
170+
self.out.write(f" {idfield_safe_name}: str\n\n")
175171

176172
required_field_names = [f for f in field_names if f not in optional_fields]
177173
optional_field_names = [f for f in field_names if f in optional_fields]
@@ -602,7 +598,8 @@ def declare_field(
602598

603599
if shortname(name) == "class":
604600
self.out.write(
605-
"""{spc} if {safename} != cls.__name__ and {safename} != cls.class_uri:
601+
"""
602+
{spc} if {safename} not in (cls.__name__, loadingOptions.vocab.get(cls.__name__)):
606603
{spc} raise ValidationException(f"tried `{{cls.__name__}}` but")
607604
{spc} except ValidationException as e:
608605
{spc} raise e
@@ -667,9 +664,10 @@ def declare_field(
667664
fmt(
668665
"""
669666
if self.{safename} is not None:
670-
if p := self.loadingOptions.rvocab.get(self.class_uri[:-len(self.{safename})]):
667+
uri = self.loadingOptions.vocab[self.{safename}]
668+
if p := self.loadingOptions.rvocab.get(uri[:-len(self.{safename})]):
671669
uri = f"{{p}}:{{self.{safename}}}"
672-
else:
670+
elif uri.startswith(_base):
673671
uri = self.{safename}
674672
u = save_relative_uri(uri, {baseurl}, {scoped_id}, {ref_scope}, relative_uris)
675673
r["{fieldname}"] = u
@@ -769,6 +767,8 @@ def secondaryfilesdsl_loader(self, inner: TypeDef) -> TypeDef:
769767
def epilogue(self, root_loader: TypeDef) -> None:
770768
"""Trigger to generate the epilouge code."""
771769

770+
self.out.write(f'_base = "{self.base_uri}"\n')
771+
772772
self.out.write("_vocab = {\n")
773773
for k in sorted(self.vocab.keys()):
774774
self.out.write(f' "{k}": "{self.vocab[k]}",\n') # noqa: B907

0 commit comments

Comments
 (0)