From 29985fb2677b1bad78b3a1ad2c718f8d5e142ebc Mon Sep 17 00:00:00 2001 From: Christian Monch Date: Mon, 15 Dec 2025 11:19:47 +0100 Subject: [PATCH 1/2] patch LinkML's ifabsent handling, add regression test --- .github/workflows/run_tests.yaml | 8 ++++- dump_things_service/patches/enabled.py | 1 + .../patches/ifabsent_processing.py | 22 +++++++++++++ .../tests/assets/schema-ifabsent-error.yaml | 31 +++++++++++++++++ .../tests/test_ifabsent_patch.py | 33 +++++++++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 dump_things_service/patches/ifabsent_processing.py create mode 100644 dump_things_service/tests/assets/schema-ifabsent-error.yaml create mode 100644 dump_things_service/tests/test_ifabsent_patch.py diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 8e34ef8..fc2aaa3 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -22,8 +22,14 @@ jobs: - name: run tests run: | - hatch run tests:run --ignore=dump_things_service/tests/test_generators.py + hatch run tests:run \ + --ignore=dump_things_service/tests/test_generators.py \ + --ignore=dump_things_service/tests/test_ifabsent_patch.py - name: run generator tests run: | hatch run tests:run dump_things_service/tests/test_generators.py + + - name: run ifabsent-patch tests + run: | + hatch run tests:run dump_things_service/tests/test_ifabsent_patch.py diff --git a/dump_things_service/patches/enabled.py b/dump_things_service/patches/enabled.py index 7f5cc56..48ea61d 100644 --- a/dump_things_service/patches/enabled.py +++ b/dump_things_service/patches/enabled.py @@ -1,5 +1,6 @@ import dump_things_service.patches.compile import dump_things_service.patches.enumerations +import dump_things_service.patches.ifabsent_processing import dump_things_service.patches.rdflib_loader import dump_things_service.patches.yamlutils diff --git a/dump_things_service/patches/ifabsent_processing.py b/dump_things_service/patches/ifabsent_processing.py new file mode 100644 index 0000000..d87c175 --- /dev/null +++ b/dump_things_service/patches/ifabsent_processing.py @@ -0,0 +1,22 @@ +""" Monkeypatch for linkml.generators.common.ifabsent_processor.IfAbsentProcessor + +Patches the ifabsent-processor to not use namespace objects. Those are not +generated in the pydantic code generator. +""" +import logging +from importlib import import_module + + +logger = logging.getLogger('dump_things_service') + + +def patched_uri_for(self, s: str) -> str: + uri = str(self.schema_view.namespaces().uri_for(s)) + curie = self.schema_view.namespaces().curie_for(uri, True) + return f"'{curie}'" if curie else self._strval(uri) + + +logger.info('patching linkml.generators.common.ifabsent_processor.IfAbsentProcessor._uri_for') + +cls = import_module('linkml.generators.common.ifabsent_processor') +cls.IfAbsentProcessor._uri_for = patched_uri_for diff --git a/dump_things_service/tests/assets/schema-ifabsent-error.yaml b/dump_things_service/tests/assets/schema-ifabsent-error.yaml new file mode 100644 index 0000000..c34ad38 --- /dev/null +++ b/dump_things_service/tests/assets/schema-ifabsent-error.yaml @@ -0,0 +1,31 @@ +id: https://example.org/ifabsent-error-trigger +name: if-absent-error-trigger +version: UNRELEASED +title: ifabsent error trigger + + +prefixes: + xsd: http://www.w3.org/2001/XMLSchema# + xyzrse: https://concepts.datalad.org/s/demo-rse-group/unreleased/ + + +types: + uriorcurie: + name: uriorcurie + uri: xsd:anyURI + repr: str + + +slots: + creator: + slot_uri: xyzrse:creator + range: uriorcurie + + +classes: + ORCID: + slots: + - creator + slot_usage: + creator: + ifabsent: uriorcurie(xsd:04fa4r544) diff --git a/dump_things_service/tests/test_ifabsent_patch.py b/dump_things_service/tests/test_ifabsent_patch.py new file mode 100644 index 0000000..95e855b --- /dev/null +++ b/dump_things_service/tests/test_ifabsent_patch.py @@ -0,0 +1,33 @@ +from importlib import reload +from pathlib import Path + +import linkml +import linkml.generators.common.ifabsent_processor as if_abs_proc + +import dump_things_service.patches.ifabsent_processing + + +# Path to a local simple test schema +schema_dir = Path(__file__).parent / 'assets' + + +def _original_uri_for(self, s: str) -> str: + uri = str(self.schema_view.namespaces().uri_for(s)) + return self.schema_view.namespaces().curie_for(uri, True, True) or self._strval(uri) + + +def test_ifabsent_patch(): + + # Patch in the faulty, original code and check for its result + if_abs_proc.IfAbsentProcessor._uri_for = _original_uri_for + gen1 = linkml.generators.PydanticGenerator(str(schema_dir / 'schema-ifabsent-error.yaml')) + x = gen1.serialize() + assert 'default=XSD["04fa4r544"]' in x + + # Apply the patch + reload(dump_things_service.patches.ifabsent_processing) + + # Check for proper code generation + gen2 = linkml.generators.PydanticGenerator(str(schema_dir / 'schema-ifabsent-error.yaml')) + y = gen2.serialize() + assert 'XSD' not in y -- 2.52.0 From d98b0282af14449986c7fce19c627e6117f8e362 Mon Sep 17 00:00:00 2001 From: Christian Monch Date: Mon, 15 Dec 2025 13:50:07 +0100 Subject: [PATCH 2/2] bump version, update CHANGELOG --- CHANGELOG.md | 7 +++++++ dump_things_service/__about__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09aa842..a9b4818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 5.3.2 (2025-12-15) + +## Bugfixes + +- add a patch for faulty `ifabsent`-code generation in LinkML's Pydantic-code generator. + + # 5.3.1 (2025-12-11) ## Bugfixes diff --git a/dump_things_service/__about__.py b/dump_things_service/__about__.py index 2e7dd83..c5a1bad 100644 --- a/dump_things_service/__about__.py +++ b/dump_things_service/__about__.py @@ -1 +1 @@ -__version__ = '5.3.1' +__version__ = '5.3.2' -- 2.52.0