diff options
| author | Han Kruiger <HanKruiger@users.noreply.github.com> | 2023-03-14 00:40:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-14 00:40:48 +0100 |
| commit | 60d98dbbf781371efd74de7d525443a11daa622e (patch) | |
| tree | 23678004e27a51559ea193b9a8e39a1b4113d8af | |
| parent | f17f97516991b43cafc320c612a353c591201bca (diff) | |
| download | rdflib-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.py | 3 | ||||
| -rw-r--r-- | test/data/contrived/README.md | 5 | ||||
| -rw-r--r-- | test/data/contrived/multiple-comments.ttl | 17 | ||||
| -rw-r--r-- | test/test_namespace/test_definednamespace_creator.py | 49 |
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")) |
