Skip to content

Commit

Permalink
Check first versionIRI then versionInfo in ontology.get_version() (#301)
Browse files Browse the repository at this point in the history
* Removed redundant infer_version in tools/ontoversion

* Added versionINFO in ontology.get_version

* VersionIRI has precendence over versionInfo and added test

* Added test for get_version
  • Loading branch information
francescalb committed Dec 7, 2021
1 parent b6c8924 commit 63ead2e
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 26 deletions.
33 changes: 25 additions & 8 deletions ontopy/ontology.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,23 +1085,40 @@ def is_defined(self, entity):
entity = self.get_by_label(entity)
return hasattr(entity, "equivalent_to") and bool(entity.equivalent_to)

def get_version(self, as_iri=False):
def get_version(self, as_iri=False) -> str:
"""Returns the version number of the ontology as inferred from the
owl:versionIRI tag.
owl:versionIRI tag or, if owl:versionIRI is not found, from
owl:versionINFO.
If `as_iri` is True, the full versionIRI is returned.
"""
version_iri_storid = self.world._abbreviate(
"http://www.w3.org/2002/07/owl#versionIRI"
)
tokens = self.get_triples(s=self.storid, p=version_iri_storid)
if (not tokens) and (as_iri is True):
raise TypeError(
"No owl:versionIRI "
f"in Ontology {self.base_iri!r}. "
"Search for owl:versionInfo with as_iri=False"
)
if tokens:
_, _, obj = tokens[0]
version_iri = self.world._unabbreviate(obj)
if as_iri:
return version_iri
return infer_version(self.base_iri, version_iri)

version_info_storid = self.world._abbreviate(
"http://www.w3.org/2002/07/owl#versionInfo"
)
tokens = self.get_triples(s=self.storid, p=version_info_storid)
if not tokens:
raise TypeError(f"No versionIRI in Ontology {self.base_iri!r}")
_, _, obj = tokens[0]
version_iri = self.world._unabbreviate(obj)
if as_iri:
return version_iri
return infer_version(self.base_iri, version_iri)
raise TypeError(
"No versionIRI or versionInfo " f"in Ontology {self.base_iri!r}"
)
_, _, version_info = tokens[0]
return version_info.strip('"').strip("'")

def set_version(self, version=None, version_iri=None):
"""Assign version to ontology by asigning owl:versionIRI.
Expand Down
29 changes: 29 additions & 0 deletions tests/ontopy/test_get_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import TYPE_CHECKING
import pytest

if TYPE_CHECKING:
from pathlib import Path


def test_get_version(repo_dir: "Path") -> None:
"""Test get_version function in ontology"""
from ontopy import get_ontology

ontopath = repo_dir / "tests" / "testonto"
testonto = get_ontology(str(ontopath) + "/testonto.ttl").load()
assert (
testonto.get_version(as_iri=True) == "http://emmo.info/testonto/0.1.0"
)
assert testonto.get_version() == "0.1.0"

testonto_noVersionIRI = get_ontology(
str(ontopath) + "/testonto_noVersionIRI.ttl"
).load()
assert testonto_noVersionIRI.get_version() == "0.1.0"
with pytest.raises(TypeError):
testonto_noVersionIRI.get_version(as_iri=True)
testonto_noVersionIRI_noVersionInfo = get_ontology(
str(ontopath) + "/testonto_noVersionIRI_noVersionInfo.ttl"
).load()
with pytest.raises(TypeError):
testonto_noVersionIRI_noVersionInfo.get_version()
3 changes: 2 additions & 1 deletion tests/testonto/testonto.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@

<http://emmo.info/testonto> rdf:type owl:Ontology ;
owl:versionIRI <http://emmo.info/testonto/0.1.0> ;
owl:imports <http://emmo.info/testonto/0.1.0/models> .
owl:imports <http://emmo.info/testonto/0.1.0/models> ;
owl:versionInfo "0.1.0" .
12 changes: 12 additions & 0 deletions tests/testonto/testonto_noVersionIRI.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@prefix : <http://emmo.info/testonto#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@base <http://emmo.info/testonto> .

<http://emmo.info/testonto> rdf:type owl:Ontology ;
owl:imports <http://emmo.info/testonto/0.1.0/models> ;
owl:versionInfo "0.1.0" .
11 changes: 11 additions & 0 deletions tests/testonto/testonto_noVersionIRI_noVersionInfo.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@prefix : <http://emmo.info/testonto#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@base <http://emmo.info/testonto> .

<http://emmo.info/testonto> rdf:type owl:Ontology ;
owl:imports <http://emmo.info/testonto/0.1.0/models> .
34 changes: 17 additions & 17 deletions tools/ontoversion
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,9 @@ import argparse
import sys

import rdflib
from rdflib.util import guess_format


def infer_version(iri, version_iri):
"""Infer version from IRI and versionIRI."""
if str(version_iri[: len(iri)]) == str(iri):
version = version_iri[len(iri) :]
else:
counter = 0
version_parts = []
for index, _ in enumerate(iri):
while iri[index] != version_iri[index + counter]:
version_parts.append(version_iri[index + counter])
counter += 1
version = "".join(version_parts)
return version.lstrip("/").rstrip("/#")
from ontopy.utils import infer_version, FMAP


def main(argv: list = None):
Expand All @@ -41,16 +29,28 @@ def main(argv: list = None):
help="IRI/file to OWL source to extract the version from.",
)
parser.add_argument(
"--format", "-f", default="xml", help='OWL format. Default is "xml".'
)
"--format",
"-f",
choices=set(list(FMAP.keys()) + list(FMAP.values())),
help="Ontology format. Default: Guess format with rdflib.guess_format.",
) # add accepted formats
try:
args = parser.parse_args(args=argv)
except SystemExit as exc:
sys.exit(exc.code) # Exit without traceback on invalid arguments

# Extract base IRI and versionIRI
graph = rdflib.Graph()
graph.parse(args.iri.rstrip("/#"), format=args.format)

# Guess format if format not given
fmt = args.format if args.format else guess_format(args.iri, fmap=FMAP)
try:
graph.parse(args.iri, format=fmt)
except Exception as err:
print("rdflib could not parse the ontology.")
print(err)
sys.exit()

iri, version_iri = list(
graph.subject_objects(
rdflib.URIRef("http://www.w3.org/2002/07/owl#versionIRI")
Expand Down

0 comments on commit 63ead2e

Please sign in to comment.