diff --git a/gen_pyi.py b/gen_pyi.py index 26d6bec..d97e1f3 100644 --- a/gen_pyi.py +++ b/gen_pyi.py @@ -1,4 +1,5 @@ import glob +import inspect import os import re import typing @@ -24,7 +25,8 @@ f.write(", ".join([f'"{n}"' for n in pyhornedowl_members])) f.write("]\n") -implemented_magic = [f"__{x}__" for x in ["invert", "and", "or", "invert"]] +implemented_magic = [f"__{x}__" for x in + ["invert", "and", "or", "invert", "iter", "getitem", "setitem", "contains", "len", "delitem"]] with open("pyhornedowl/__init__.pyi", "w") as f: f.write("import typing\n") @@ -67,7 +69,10 @@ for line in doc.splitlines(): f.write(f" {line}\n") f.write(" \"\"\"\n") - elif hasattr(member, "__doc__"): + + continue + + if hasattr(member, "__doc__"): doc = member.__doc__ if doc is not None: lines = doc.splitlines() @@ -87,6 +92,13 @@ f.write(f" {sign}\n") doc = "\n".join([f" {l}" for l in lines[annotations_end+2:]]) f.write(f' """\n{doc}\n """\n\n') + + continue + + if callable(member): + f.write(f" def {member_name}{inspect.signature(member)}:\n ...\n\n") + + continue f.write("\n") diff --git a/pyhornedowl/__init__.pyi b/pyhornedowl/__init__.pyi index 85604fe..848a772 100644 --- a/pyhornedowl/__init__.pyi +++ b/pyhornedowl/__init__.pyi @@ -4,6 +4,7 @@ from typing_extensions import deprecated import model + class PyIndexedOntology: """ Represents a loaded ontology. @@ -305,6 +306,24 @@ class IndexCreationStrategy: """ class PrefixMapping: + def __iter__(self, /): + ... + + def __len__(self, /): + ... + + def __getitem__(self, key, /): + ... + + def __setitem__(self, key, value, /): + ... + + def __delitem__(self, key, /): + ... + + def __contains__(self, key, /): + ... + def add_default_prefix_names(self) -> None: """ Adds the prefix for rdf, rdfs, xsd, and owl @@ -329,7 +348,7 @@ class PrefixMapping: """ ... - def shring_iri(self, iri: str) -> str: + def shrink_iri(self, iri: str) -> str: """ Shrinks an absolute IRI to a CURIE. Throws a ValueError on failure """ diff --git a/src/prefix_mapping.rs b/src/prefix_mapping.rs index d56e8fb..8bbca7f 100644 --- a/src/prefix_mapping.rs +++ b/src/prefix_mapping.rs @@ -26,8 +26,35 @@ impl From for curie::PrefixMapping { } } +#[pyclass] +struct Iter { + inner: std::vec::IntoIter<(String, String)> +} + +#[pymethods] +impl Iter { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { + slf + } + + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<(String, String)> { + slf.inner.next() + } +} + #[pymethods] impl PrefixMapping { + + /// __iter__(self) -> typing.Iterable[typing.Tuple[str, str]] + /// + /// Get an iterator over all prefixes + fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { + let iter = Iter { + inner: slf.0.mappings().map(|(x,y)| ((x.clone(), y.clone()))).collect::>().into_iter(), + }; + Py::new(slf.py(), iter) + } + pub fn __getitem__(&self, key: &str) -> PyResult { self.0 .expand_curie(&curie::Curie::new(Some(key), "")) @@ -102,7 +129,7 @@ impl PrefixMapping { .map_err(to_py_err!("Invalid or unknown prefix")) } - /// shring_iri(self, iri: str) -> str + /// shrink_iri(self, iri: str) -> str /// /// Shrinks an absolute IRI to a CURIE. Throws a ValueError on failure pub fn shrink_iri(&self, iri: &str) -> PyResult { diff --git a/test/resources/gen.sh b/test/resources/gen.sh old mode 100644 new mode 100755 index b0d053c..c5587d3 --- a/test/resources/gen.sh +++ b/test/resources/gen.sh @@ -2,11 +2,25 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +FILES=("simple" "prefix") + +EMPTY_PREFIX="https://example.com/" + +for f in "${FILES[@]}"; do + robot convert -i "$SCRIPT_DIR/$f.omn" -o "$SCRIPT_DIR/$f.ofn" + sed -i "1iPrefix(:=<$EMPTY_PREFIX>)" "$SCRIPT_DIR/$f.ofn" + + robot convert -i "$SCRIPT_DIR/$f.omn" -o "$SCRIPT_DIR/$f.owx" + sed -i "10i " "$SCRIPT_DIR/$f.owx" + + robot convert -i "$SCRIPT_DIR/$f.omn" -o "$SCRIPT_DIR/$f.owl" + # no empty prefix in rdf/xml? + + ln -f "$SCRIPT_DIR/$f.omn" "$SCRIPT_DIR/$f.omn.raw" + ln -f "$SCRIPT_DIR/$f.ofn" "$SCRIPT_DIR/$f.ofn.raw" + ln -f "$SCRIPT_DIR/$f.owx" "$SCRIPT_DIR/$f.owx.raw" + ln -f "$SCRIPT_DIR/$f.owl" "$SCRIPT_DIR/$f.owl.raw" +done + + -robot convert -i "$SCRIPT_DIR/simple.omn" -o "$SCRIPT_DIR/simple.ofn" -robot convert -i "$SCRIPT_DIR/simple.omn" -o "$SCRIPT_DIR/simple.owx" -robot convert -i "$SCRIPT_DIR/simple.omn" -o "$SCRIPT_DIR/simple.owl" -ln -f "$SCRIPT_DIR/simple.omn" "$SCRIPT_DIR/simple.omn.raw" -ln -f "$SCRIPT_DIR/simple.ofn" "$SCRIPT_DIR/simple.ofn.raw" -ln -f "$SCRIPT_DIR/simple.owx" "$SCRIPT_DIR/simple.owx.raw" -ln -f "$SCRIPT_DIR/simple.owl" "$SCRIPT_DIR/simple.owl.raw" diff --git a/test/resources/prefix.ofn b/test/resources/prefix.ofn new file mode 100644 index 0000000..af9c3cc --- /dev/null +++ b/test/resources/prefix.ofn @@ -0,0 +1,18 @@ +Prefix(:=) +Prefix(ex1:=) +Prefix(ex2:=) +Prefix(ex3:=) +Prefix(owl:=) +Prefix(rdf:=) +Prefix(xml:=) +Prefix(xsd:=) +Prefix(rdfs:=) + + +Ontology( +Declaration(Class()) +Declaration(Class(ex1:A)) +Declaration(Class(ex2:A)) +Declaration(Class(ex3:A)) + +) \ No newline at end of file diff --git a/test/resources/prefix.ofn.raw b/test/resources/prefix.ofn.raw new file mode 100644 index 0000000..af9c3cc --- /dev/null +++ b/test/resources/prefix.ofn.raw @@ -0,0 +1,18 @@ +Prefix(:=) +Prefix(ex1:=) +Prefix(ex2:=) +Prefix(ex3:=) +Prefix(owl:=) +Prefix(rdf:=) +Prefix(xml:=) +Prefix(xsd:=) +Prefix(rdfs:=) + + +Ontology( +Declaration(Class()) +Declaration(Class(ex1:A)) +Declaration(Class(ex2:A)) +Declaration(Class(ex3:A)) + +) \ No newline at end of file diff --git a/test/resources/prefix.omn b/test/resources/prefix.omn new file mode 100644 index 0000000..1571a6d --- /dev/null +++ b/test/resources/prefix.omn @@ -0,0 +1,10 @@ +Prefix: : +Prefix: ex1: +Prefix: ex2: +Prefix: ex3: +Ontology: + Class: ex1:A + Class: ex2:A + Class: ex3:A + Class: A + diff --git a/test/resources/prefix.omn.raw b/test/resources/prefix.omn.raw new file mode 100644 index 0000000..1571a6d --- /dev/null +++ b/test/resources/prefix.omn.raw @@ -0,0 +1,10 @@ +Prefix: : +Prefix: ex1: +Prefix: ex2: +Prefix: ex3: +Ontology: + Class: ex1:A + Class: ex2:A + Class: ex3:A + Class: A + diff --git a/test/resources/prefix.owl b/test/resources/prefix.owl new file mode 100644 index 0000000..fbdaa2c --- /dev/null +++ b/test/resources/prefix.owl @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/prefix.owl.raw b/test/resources/prefix.owl.raw new file mode 100644 index 0000000..fbdaa2c --- /dev/null +++ b/test/resources/prefix.owl.raw @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/prefix.owx b/test/resources/prefix.owx new file mode 100644 index 0000000..c92345d --- /dev/null +++ b/test/resources/prefix.owx @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/prefix.owx.raw b/test/resources/prefix.owx.raw new file mode 100644 index 0000000..c92345d --- /dev/null +++ b/test/resources/prefix.owx.raw @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/simple.ofn b/test/resources/simple.ofn index 55e834b..859d2ee 100644 --- a/test/resources/simple.ofn +++ b/test/resources/simple.ofn @@ -1,3 +1,4 @@ +Prefix(:=) Prefix(owl:=) Prefix(rdf:=) Prefix(xml:=) diff --git a/test/resources/simple.ofn.raw b/test/resources/simple.ofn.raw index 55e834b..859d2ee 100644 --- a/test/resources/simple.ofn.raw +++ b/test/resources/simple.ofn.raw @@ -1,3 +1,4 @@ +Prefix(:=) Prefix(owl:=) Prefix(rdf:=) Prefix(xml:=) diff --git a/test/resources/simple.omn b/test/resources/simple.omn index 1507773..2cfb60b 100644 --- a/test/resources/simple.omn +++ b/test/resources/simple.omn @@ -1,7 +1,9 @@ Prefix: : + Ontology: - Class: A + Class: :A Annotations: rdfs:label "ClassA" - Class: B SubClassOf: A + Class: :B Annotations: rdfs:label "ClassB" - Class: C \ No newline at end of file + SubClassOf: :A + Class: :C diff --git a/test/resources/simple.omn.raw b/test/resources/simple.omn.raw index 1507773..2cfb60b 100644 --- a/test/resources/simple.omn.raw +++ b/test/resources/simple.omn.raw @@ -1,7 +1,9 @@ Prefix: : + Ontology: - Class: A + Class: :A Annotations: rdfs:label "ClassA" - Class: B SubClassOf: A + Class: :B Annotations: rdfs:label "ClassB" - Class: C \ No newline at end of file + SubClassOf: :A + Class: :C diff --git a/test/resources/simple.owl b/test/resources/simple.owl index 3b23e47..9b6d054 100644 --- a/test/resources/simple.owl +++ b/test/resources/simple.owl @@ -45,5 +45,5 @@ - + diff --git a/test/resources/simple.owl.raw b/test/resources/simple.owl.raw index 3b23e47..9b6d054 100644 --- a/test/resources/simple.owl.raw +++ b/test/resources/simple.owl.raw @@ -45,5 +45,5 @@ - + diff --git a/test/resources/simple.owx b/test/resources/simple.owx index db90341..8103cf2 100644 --- a/test/resources/simple.owx +++ b/test/resources/simple.owx @@ -7,6 +7,7 @@ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"> + @@ -37,5 +38,5 @@ - + diff --git a/test/resources/simple.owx.raw b/test/resources/simple.owx.raw index db90341..8103cf2 100644 --- a/test/resources/simple.owx.raw +++ b/test/resources/simple.owx.raw @@ -7,6 +7,7 @@ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"> + @@ -37,5 +38,5 @@ - + diff --git a/test/test_prefix.py b/test/test_prefix.py new file mode 100644 index 0000000..25b2f62 --- /dev/null +++ b/test/test_prefix.py @@ -0,0 +1,35 @@ +import typing +import unittest + +import pyhornedowl +from test_base import r + +SERIALIZATIONS: typing.List[typing.Literal['ofn', 'owx', 'owl']] = ['ofn', 'owx', 'owl'] + + +class PrefixTestCase(unittest.TestCase): + def test_prefix(self): + for s in SERIALIZATIONS: + with self.subTest(serialization=s): + if s == 'owl': + self.skipTest('RDF/XML parser does not return prefixes') + + o = pyhornedowl.open_ontology(r(f'prefix.{s}'), s) + + actual = set(iter(o.prefix_mapping)) + expected = set({"": "https://example.com/", + "ex1": "https://example.com/1", + "ex2": "https://example.com/2", + "ex3": "https://example.com/3", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "owl": "http://www.w3.org/2002/07/owl#", + "xml": "http://www.w3.org/XML/1998/namespace", + }.items()) + + self.assertSetEqual(expected, actual) + + +if __name__ == '__main__': + unittest.main()