summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHan Kruiger <HanKruiger@users.noreply.github.com>2023-03-14 00:40:48 +0100
committerGitHub <noreply@github.com>2023-03-14 00:40:48 +0100
commit60d98dbbf781371efd74de7d525443a11daa622e (patch)
tree23678004e27a51559ea193b9a8e39a1b4113d8af
parentf17f97516991b43cafc320c612a353c591201bca (diff)
downloadrdflib-60d98dbbf781371efd74de7d525443a11daa622e.tar.gz
fix: correctly handle resources with multiple comments in defined_namespace_creator (#2254)
FIxed a bug in defined_namespace_creator so that when a resource in an ontology is commented on multiple times (with e.g. rdfs:comment), it creates only a single class variable in the resulting DefinedNamespace where the Python comment is the concatenation of the rdfs:comments.
-rw-r--r--rdflib/tools/defined_namespace_creator.py3
-rw-r--r--test/data/contrived/README.md5
-rw-r--r--test/data/contrived/multiple-comments.ttl17
-rw-r--r--test/test_namespace/test_definednamespace_creator.py49
4 files changed, 73 insertions, 1 deletions
diff --git a/rdflib/tools/defined_namespace_creator.py b/rdflib/tools/defined_namespace_creator.py
index 0c93ea75..1076cd6e 100644
--- a/rdflib/tools/defined_namespace_creator.py
+++ b/rdflib/tools/defined_namespace_creator.py
@@ -77,7 +77,7 @@ def get_target_namespace_elements(
) -> Tuple[List[Tuple[str, str]], List[str]]:
namespaces = {"dcterms": DCTERMS, "owl": OWL, "rdfs": RDFS, "skos": SKOS}
q = """
- SELECT DISTINCT ?s ?def
+ SELECT ?s (GROUP_CONCAT(DISTINCT STR(?def)) AS ?defs)
WHERE {
# all things in the RDF data (anything RDF.type...)
?s a ?o .
@@ -90,6 +90,7 @@ def get_target_namespace_elements(
# only get results for the target namespace (supplied by user)
FILTER STRSTARTS(STR(?s), "xxx")
}
+ GROUP BY ?s
""".replace(
"xxx", target_namespace
)
diff --git a/test/data/contrived/README.md b/test/data/contrived/README.md
new file mode 100644
index 00000000..fd1e0e7d
--- /dev/null
+++ b/test/data/contrived/README.md
@@ -0,0 +1,5 @@
+# Contrived Test Data
+
+This directory contains test data contrived for specific purposes. Files in this
+directory should clearly indicate their purpose with a comment.
+
diff --git a/test/data/contrived/multiple-comments.ttl b/test/data/contrived/multiple-comments.ttl
new file mode 100644
index 00000000..a2c07371
--- /dev/null
+++ b/test/data/contrived/multiple-comments.ttl
@@ -0,0 +1,17 @@
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix ex: <http://example.org/multiline-string-example#> .
+
+# This file contains a RDF class with multiple rdfs:comment properties and is
+# used to verify the RDFLib defined namespace creator. It is used in
+# </test/test_namespace/test_definednamespace_creator.py>.
+
+<http://example.org/multiline-string-example>
+ a owl:Ontology .
+
+ex:SomeClass a rdfs:Class, owl:Class;
+ rdfs:label "Some class"@en;
+ rdfs:comment "If one uses multiple comment properties, "@en;
+ rdfs:comment "then it should still only create a single class variable."@en;
+ rdfs:isDefinedBy <http://example.org/multiline-string-example>;
+.
diff --git a/test/test_namespace/test_definednamespace_creator.py b/test/test_namespace/test_definednamespace_creator.py
index 65734b21..8866a05d 100644
--- a/test/test_namespace/test_definednamespace_creator.py
+++ b/test/test_namespace/test_definednamespace_creator.py
@@ -114,3 +114,52 @@ def test_definednamespace_creator_bad_ns():
universal_newlines=True,
)
assert completed.returncode == 1, "subprocess exited incorrectly (failure expected)"
+
+
+def test_definednamespace_creator_multiple_comments():
+ """
+ Tests that only a single URIRef is declared, even when multiple
+ rdfs:comments are linked to the resource.
+ """
+
+ definednamespace_script = (
+ Path(__file__).parent.parent.parent
+ / "rdflib"
+ / "tools"
+ / "defined_namespace_creator.py"
+ )
+ multiple_comments_data_file = (
+ Path(__file__).parent.parent / "data" / "contrived" / "multiple-comments.ttl"
+ )
+ print("\n")
+ print(f"Using {definednamespace_script}...")
+ print(f"Testing {multiple_comments_data_file}...")
+ completed = subprocess.run(
+ [
+ sys.executable,
+ str(definednamespace_script),
+ str(multiple_comments_data_file),
+ "http://example.org/multiline-string-example#",
+ "MULTILINESTRINGEXAMPLE",
+ ],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ assert completed.returncode == 0, "subprocess exited incorrectly"
+ assert Path.is_file(
+ Path("_MULTILINESTRINGEXAMPLE.py")
+ ), "_MULTILINESTRINGEXAMPLE.py file not created"
+
+ some_class_count = 0
+ with open(Path("_MULTILINESTRINGEXAMPLE.py")) as f:
+ for line in f.readlines():
+ if "SomeClass: URIRef" in line:
+ some_class_count += 1
+
+ assert (
+ some_class_count == 1
+ ), f"found {some_class_count} SomeClass definitions instead of 1."
+
+ # cleanup
+ Path.unlink(Path("_MULTILINESTRINGEXAMPLE.py"))