From 774763ec580fbb9f4a944b1d12100511f28d1e09 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Fri, 7 Aug 2026 12:49:23 +0200 Subject: [PATCH] Move IRI validation from the constructor to the _validate() method. This is more consistent with how other invalid values are treated in openMINDS Python, and is more forgiving for the common case where an IRI contains whitespace, which is strictly speaking not allowed, but is handled by most web browsers. Fixes #93 --- pipeline/src/base.py | 7 +++++-- pipeline/tests/test_instantiation.py | 16 +++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/pipeline/src/base.py b/pipeline/src/base.py index 4635395d..a3e9ed53 100644 --- a/pipeline/src/base.py +++ b/pipeline/src/base.py @@ -315,8 +315,6 @@ def __init__(self, value: Union[str, IRI]): iri = value.value else: iri = value - if not rfc3987.match(iri, rule="IRI"): - raise ValueError("Invalid IRI") self.value: str = iri def __eq__(self, other): @@ -337,4 +335,9 @@ def _validate(self, ignore=None, seen=None): failures = defaultdict(list) if self.value.startswith("file") and "value" not in ignore: failures["value"].append("IRI points to a local file path") + if not rfc3987.match(self.value, rule="IRI"): + if rfc3987.match(self.value.replace(" ", "%20"), rule="IRI"): + failures["value"].append("Invalid IRI - replace spaces with '%20'") + else: + failures["value"].append("Invalid IRI") return failures diff --git a/pipeline/tests/test_instantiation.py b/pipeline/tests/test_instantiation.py index 723231a2..715eddf8 100644 --- a/pipeline/tests/test_instantiation.py +++ b/pipeline/tests/test_instantiation.py @@ -74,11 +74,17 @@ def test_IRI(): assert not failures else: assert failures["value"][0] == "IRI points to a local file path" - invalid_iris = ["/path/to/my/file.txt"] - for value in invalid_iris: - with pytest.raises(ValueError) as exc_info: - iri = IRI(value) - assert exc_info.value.args[0] == "Invalid IRI" + invalid_iris = [ + ("/path/to/my/file.txt", "Invalid IRI"), + ("https://example.com/path with spaces/to/my/file.txt", "Invalid IRI - replace spaces with '%20'"), + ("https://data-proxy.ebrains.eu/api/v1/buckets/report%.pdf", "Invalid IRI") # lone '%' not allowed + ] + for value, expected_message in invalid_iris: + iri = IRI(value) + assert iri.value == value + failures = iri._validate() + assert len(failures["value"]) == 1 + assert failures["value"][0] == expected_message def test_link():