Skip to content

Commit ee603d4

Browse files
GlassOfWhiskeymr-c
andauthored
Add prefix-based inheritance to codegen (#1028)
Adds the possibility to specify a parent parser for each prefix in a Schema SALAD specification. The idea is that each extensions could come with a different namespace, and would define its own parser for its classes. With this commit, a user can leverage the `--codegen-parent` option to explicitly map a prefix to a parent parser (e.g., a Python module) with a "prefix=package" syntax. For example: ```bash --codegen-parent "https://w3id.org/cwl/salad=schema_salad.metaschema" ``` Inheritance is not able to automatically reconstruct the whole class hierarchy, meaning that if B inherits from A and C inherits from B, the user must manually specify the mapping also for namespace A. However, we do not expect huge parser hierarchies for schema SALAD specifications. Co-authored-by: Michael R. Crusoe <1330696+mr-c@users.noreply.github.com>
1 parent d48545d commit ee603d4

13 files changed

Lines changed: 1000 additions & 1172 deletions

File tree

.github/workflows/ci-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- name: Upload coverage to Codecov
6262
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6
6363
with:
64-
fail_ci_if_error: true
64+
fail_ci_if_error: false
6565
env:
6666
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
6767

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ diff_pylint_report: pylint_report.txt
122122
diff-quality --compare-branch=origin/main --violations=pylint pylint_report.txt
123123

124124
.coverage:
125-
pytest --cov --cov-config=.coveragerc --cov-report= ${PYTEST_EXTRA}
125+
pytest --cov --cov-config=.coveragerc --cov-report= --junitxml=junit.xml -o junit_family=legacy ${PYTEST_EXTRA}
126126
$(COVBASE) -m schema_salad.main \
127127
--print-jsonld-context src/schema_salad/metaschema/metaschema.yml \
128128
> /dev/null
@@ -226,7 +226,7 @@ release:
226226
flake8: FORCE
227227
flake8 $(PYSOURCES)
228228

229-
src/schema_salad/metaschema.py: src/schema_salad/codegen_base.py src/schema_salad/python_codegen_support.py src/schema_salad/python_codegen.py src/schema_salad/metaschema/*.yml
229+
src/schema_salad/metaschema.py: src/schema_salad/codegen_base.py src/schema_salad/runtime.py src/schema_salad/python_codegen.py src/schema_salad/metaschema/*.yml
230230
schema-salad-tool --codegen python src/schema_salad/metaschema/metaschema.yml > $@
231231

232232
vpath %.yml src/schema_salad/tests/cpp_tests

README.rst

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,20 @@ Schema salad can be used as a command line tool or imported as a Python module::
5151

5252
$ schema-salad-tool
5353
usage: schema-salad-tool [-h] [--rdf-serializer RDF_SERIALIZER] [--skip-schemas]
54-
[--strict-foreign-properties] [--print-jsonld-context]
55-
[--print-rdfs] [--print-avro] [--print-rdf] [--print-pre]
56-
[--print-index] [--print-metadata] [--print-inheritance-dot]
57-
[--print-fieldrefs-dot] [--codegen language] [--codegen-target CODEGEN_TARGET]
58-
[--codegen-examples directory] [--codegen-package dotted.package]
59-
[--codegen-copyright copyright_string] [--print-oneline]
60-
[--print-doc] [--strict | --non-strict]
54+
[--strict-foreign-properties] [--version]
55+
[--print-jsonld-context | --print-rdfs | --print-avro |
56+
--print-rdf | --print-pre | --print-index | --print-metadata |
57+
--print-inheritance-dot | --print-fieldrefs-dot | --codegen LANGUAGE |
58+
--print-oneline | --print-doc]
59+
[--codegen-target CODEGEN_TARGET] [--codegen-examples DIRECTORY]
60+
[--codegen-package DOTTED.PACKAGE] [--codegen-parent PARENTS_MAP]
61+
[--codegen-copyright COPYRIGHT_STRING]
62+
[--codegen-spdx-copyright-text SPDX_COPYRIGHT_TEXT [SPDX_COPYRIGHT_TEXT ...]]
63+
[--codegen-spdx-license-identifier SPDX_LICENSE_IDENTIFIER]
64+
[--codegen-parser-info PARSER_INFO] [--strict | --non-strict]
6165
[--verbose | --quiet | --debug] [--only ONLY] [--redirect REDIRECT]
6266
[--brand BRAND] [--brandlink BRANDLINK] [--brandstyle BRANDSTYLE]
63-
[--brandinverse] [--primtype PRIMTYPE] [--version]
64-
[schema] [document]
67+
[--brandinverse] [--primtype PRIMTYPE] [schema] [document ...]
6568

6669
$ python
6770
>>> import schema_salad

src/schema_salad/codegen.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def codegen(
3131
examples: str | None = None,
3232
package: str | None = None,
3333
copyright: str | None = None,
34+
parents_map: dict[str, str] | None = None,
3435
spdx_copyright_text: list[str] | None = None,
3536
spdx_license_identifier: str | None = None,
3637
parser_info: str | None = None,
@@ -87,7 +88,11 @@ def codegen(
8788
return
8889
case "python":
8990
gen = PythonCodeGen(
90-
dest, copyright=copyright, parser_info=info, salad_version=salad_version
91+
dest,
92+
copyright=copyright,
93+
parents_map=parents_map,
94+
parser_info=info,
95+
salad_version=salad_version,
9196
)
9297
case "java":
9398
gen = JavaCodeGen(

src/schema_salad/main.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@
2929
_logger: Final = logging.getLogger("salad")
3030

3131

32+
def parse_kv(pair: str) -> tuple[str, str]:
33+
"""Parse `key=value` arguments into a tuple of `key` and `value`."""
34+
try:
35+
k, v = pair.split("=", 1)
36+
return k, v
37+
except ValueError as e:
38+
raise argparse.ArgumentTypeError(f"Invalid format: '{pair}', expected key=value") from e
39+
40+
3241
def printrdf(
3342
workflow: str,
3443
wf: CommentedMap | CommentedSeq,
@@ -147,6 +156,15 @@ def arg_parser() -> argparse.ArgumentParser:
147156
"from the base URL (Java/TypeScript/.Net/Dlang only).",
148157
)
149158

159+
codegen_opts.add_argument(
160+
"--codegen-parent",
161+
type=parse_kv,
162+
metavar="PARENTS_MAP",
163+
action="append",
164+
default=None,
165+
help="Optional mapping of prefix into parent package for generated classes (Python only).",
166+
)
167+
150168
codegen_opts.add_argument(
151169
"--codegen-copyright",
152170
type=str,
@@ -351,6 +369,7 @@ def main(argsl: list[str] | None = None) -> int:
351369
examples=args.codegen_examples,
352370
package=args.codegen_package,
353371
copyright=args.codegen_copyright,
372+
parents_map=dict(args.codegen_parent or []),
354373
spdx_license_identifier=args.codegen_spdx_license_identifier,
355374
spdx_copyright_text=args.codegen_spdx_copyright_text,
356375
parser_info=args.codegen_parser_info,

0 commit comments

Comments
 (0)