Skip to content

Commit daf7967

Browse files
Fix class detection for namespaced classes (Py)
This commit asjusts the Python generated parser to correctly deal with namespaced classes (e.g., those coming from cwltool extensions).
1 parent f3518e2 commit daf7967

File tree

4 files changed

+54
-33
lines changed

4 files changed

+54
-33
lines changed

schema_salad/codegen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from .typescript_codegen import TypeScriptCodeGen
2020
from .utils import aslist
2121

22-
FIELD_SORT_ORDER = ["id", "class", "name"]
22+
FIELD_SORT_ORDER = ["class", "id", "name"]
2323

2424

2525
def codegen(

schema_salad/metaschema.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,8 @@ class RecordField(Documented):
11621162
A field of a record.
11631163
"""
11641164

1165+
class_uri = "https://w3id.org/cwl/salad#RecordField"
1166+
11651167
def __init__(
11661168
self,
11671169
name: Any,
@@ -1428,6 +1430,8 @@ def save(
14281430

14291431

14301432
class RecordSchema(Saveable):
1433+
class_uri = "https://w3id.org/cwl/salad#RecordSchema"
1434+
14311435
def __init__(
14321436
self,
14331437
type_: Any,
@@ -1632,6 +1636,8 @@ class EnumSchema(Saveable):
16321636
16331637
"""
16341638

1639+
class_uri = "https://w3id.org/cwl/salad#EnumSchema"
1640+
16351641
def __init__(
16361642
self,
16371643
symbols: Any,
@@ -1898,6 +1904,8 @@ def save(
18981904

18991905

19001906
class ArraySchema(Saveable):
1907+
class_uri = "https://w3id.org/cwl/salad#ArraySchema"
1908+
19011909
def __init__(
19021910
self,
19031911
items: Any,
@@ -2097,6 +2105,8 @@ def save(
20972105

20982106

20992107
class MapSchema(Saveable):
2108+
class_uri = "https://w3id.org/cwl/salad#MapSchema"
2109+
21002110
def __init__(
21012111
self,
21022112
type_: Any,
@@ -2296,6 +2306,8 @@ def save(
22962306

22972307

22982308
class UnionSchema(Saveable):
2309+
class_uri = "https://w3id.org/cwl/salad#UnionSchema"
2310+
22992311
def __init__(
23002312
self,
23012313
names: Any,
@@ -2501,6 +2513,8 @@ class JsonldPredicate(Saveable):
25012513
25022514
"""
25032515

2516+
class_uri = "https://w3id.org/cwl/salad#JsonldPredicate"
2517+
25042518
def __init__(
25052519
self,
25062520
_id: Optional[Any] = None,
@@ -3239,6 +3253,8 @@ def save(
32393253

32403254

32413255
class SpecializeDef(Saveable):
3256+
class_uri = "https://w3id.org/cwl/salad#SpecializeDef"
3257+
32423258
def __init__(
32433259
self,
32443260
specializeFrom: Any,
@@ -3463,6 +3479,8 @@ class SaladRecordField(RecordField):
34633479
A field of a record.
34643480
"""
34653481

3482+
class_uri = "https://w3id.org/cwl/salad#SaladRecordField"
3483+
34663484
def __init__(
34673485
self,
34683486
name: Any,
@@ -3844,6 +3862,8 @@ def save(
38443862

38453863

38463864
class SaladRecordSchema(NamedType, RecordSchema, SchemaDefinedType):
3865+
class_uri = "https://w3id.org/cwl/salad#SaladRecordSchema"
3866+
38473867
def __init__(
38483868
self,
38493869
name: Any,
@@ -4705,6 +4725,8 @@ class SaladEnumSchema(NamedType, EnumSchema, SchemaDefinedType):
47054725
47064726
"""
47074727

4728+
class_uri = "https://w3id.org/cwl/salad#SaladEnumSchema"
4729+
47084730
def __init__(
47094731
self,
47104732
symbols: Any,
@@ -5446,6 +5468,8 @@ class SaladMapSchema(NamedType, MapSchema, SchemaDefinedType):
54465468
54475469
"""
54485470

5471+
class_uri = "https://w3id.org/cwl/salad#SaladMapSchema"
5472+
54495473
def __init__(
54505474
self,
54515475
name: Any,
@@ -6131,6 +6155,8 @@ class SaladUnionSchema(NamedType, UnionSchema, DocType):
61316155
61326156
"""
61336157

6158+
class_uri = "https://w3id.org/cwl/salad#SaladUnionSchema"
6159+
61346160
def __init__(
61356161
self,
61366162
name: Any,
@@ -6757,6 +6783,8 @@ class Documentation(NamedType, DocType):
67576783
67586784
"""
67596785

6786+
class_uri = "https://w3id.org/cwl/salad#Documentation"
6787+
67606788
def __init__(
67616789
self,
67626790
name: Any,

schema_salad/python_codegen.py

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def begin_class(
143143
idfield: str,
144144
optional_fields: set[str],
145145
) -> None:
146+
class_uri = classname
146147
classname = self.safe_name(classname)
147148

148149
if extends:
@@ -163,6 +164,8 @@ def begin_class(
163164
self.out.write(" pass\n\n\n")
164165
return
165166

167+
self.out.write(f' class_uri = "{class_uri}"\n\n')
168+
166169
required_field_names = [f for f in field_names if f not in optional_fields]
167170
optional_field_names = [f for f in field_names if f in optional_fields]
168171

@@ -276,27 +279,6 @@ def save(
276279
"""
277280
)
278281

279-
if "class" in field_names:
280-
self.out.write(
281-
"""
282-
if "class" not in _doc:
283-
raise ValidationException("Missing 'class' field")
284-
if _doc.get("class") != "{class_}":
285-
raise ValidationException("tried `{class_}` but")
286-
287-
""".format(
288-
class_=classname
289-
)
290-
)
291-
292-
self.serializer.write(
293-
"""
294-
r["class"] = "{class_}"
295-
""".format(
296-
class_=classname
297-
)
298-
)
299-
300282
def end_class(self, classname: str, field_names: list[str]) -> None:
301283
"""Signal that we are done with this class."""
302284
if self.current_class_is_abstract:
@@ -554,9 +536,6 @@ def declare_field(
554536
if self.current_class_is_abstract:
555537
return
556538

557-
if shortname(name) == "class":
558-
return
559-
560539
if optional:
561540
self.out.write(f""" {self.safe_name(name)} = None\n""")
562541
self.out.write(f""" if "{shortname(name)}" in _doc:\n""") # noqa: B907
@@ -608,8 +587,22 @@ def declare_field(
608587
spc=spc,
609588
)
610589
)
611-
self.out.write(
612-
"""
590+
591+
if shortname(name) == "class":
592+
self.out.write(
593+
"""{spc} if {safename} != cls.__name__ and {safename} != cls.class_uri:
594+
{spc} raise ValidationException(f"tried `{{cls.__name__}}` but")
595+
{spc} except ValidationException as e:
596+
{spc} raise e
597+
""".format(
598+
safename=self.safe_name(name),
599+
spc=spc,
600+
)
601+
)
602+
603+
else:
604+
self.out.write(
605+
"""
613606
{spc} except ValidationException as e:
614607
{spc} error_message, to_print, verb_tensage = parse_errors(str(e))
615608
@@ -647,10 +640,10 @@ def declare_field(
647640
{spc} )
648641
{spc} )
649642
""".format(
650-
fieldname=shortname(name),
651-
spc=spc,
643+
fieldname=shortname(name),
644+
spc=spc,
645+
)
652646
)
653-
)
654647

655648
if name == self.idfield or not self.idfield:
656649
baseurl = "base_url"

schema_salad/tests/test_codegen_errors.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ def test_error_message5(tmp_path: Path) -> None:
6767
def test_error_message6(tmp_path: Path) -> None:
6868
t = "test_schema/test6.cwl"
6969
match = r"""\*\s+tried\s+`CommandLineTool`\s+but
70-
\s+Missing\s+'class'\s+field
70+
\s+missing\s+required\s+field\s+`class`
7171
+\*\s+tried\s+`ExpressionTool`\s+but
72-
\s+Missing\s+'class'\s+field
72+
\s+missing\s+required\s+field\s+`class`
7373
+\*\s+tried\s+`Workflow`\s+but
74-
\s+Missing\s+'class'\s+field"""
74+
\s+missing\s+required\s+field\s+`class`"""
7575
path = get_data("tests/" + t)
7676
assert path
7777
with pytest.raises(ValidationException, match=match):

0 commit comments

Comments
 (0)