Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check first versionIRI then versionInfo in ontology.get_version() #301

Merged
merged 9 commits into from
Dec 7, 2021
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