From 01174cf5124ed5f0acba38eb3ef51b42479b6e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Dom=C3=ADnguez?= Date: Tue, 23 Mar 2021 14:08:38 +0100 Subject: [PATCH 1/3] Add autocompletion for namespaces. --- osp/core/ontology/namespace.py | 49 +++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/osp/core/ontology/namespace.py b/osp/core/ontology/namespace.py index 8f29a70a..1d5b527f 100644 --- a/osp/core/ontology/namespace.py +++ b/osp/core/ontology/namespace.py @@ -4,7 +4,7 @@ from collections.abc import Iterable import rdflib import logging - +import itertools from osp.core.ontology.entity import OntologyEntity from osp.core.ontology.cuba import rdflib_cuba from osp.core.ontology.yml.case_insensitivity import \ @@ -31,6 +31,17 @@ def __init__(self, name, namespace_registry, iri): self._reference_by_label = \ namespace_registry._get_reference_by_label(self._iri) + def __dir__(self): + """Attributes available for the OntologyNamespace class. + + Returns: + Iterable: the available attributes, which include the methods and + the ontology entities in the namespace. + """ + entity_autocompletion = self._iter_labels() \ + if self._reference_by_label else self._iter_suffixes() + return itertools.chain(super().__dir__(), entity_autocompletion) + def __str__(self): """Transform the namespace to a human readable string. @@ -240,20 +251,46 @@ def _get_from_label(self, label, lang=None, case_sensitive=False): results))) return results[0] - def __iter__(self): - """Iterate over the ontology entities in the namespace. + def _iter_iris(self): + """Iterate over the IRIs of the ontology entities in the namespace. - :return: An iterator over the entities. - :rtype: Iterator[OntologyEntity] + :return: An iterator over the entity IRIs. + :rtype: Iterator[rdflib.URIRef] """ types = [rdflib.OWL.DatatypeProperty, rdflib.OWL.ObjectProperty, rdflib.OWL.Class] - return (self._namespace_registry.from_iri(s) + return (s for t in types for s, _, _ in self._graph.triples((None, rdflib.RDF.type, t)) if s in self) + def __iter__(self): + """Iterate over the ontology entities in the namespace. + + :return: An iterator over the entities. + :rtype: Iterator[OntologyEntity] + """ + return (self._namespace_registry.from_iri(iri) + for iri in self._iter_iris()) + + def _iter_labels(self): + """Iterate over the labels of the ontology entities in the namespace. + + :return: An iterator over the entity labels. + :rtype: Iterator[str] + """ + return itertools.chain(*(self._get_labels_for_iri(iri) + for iri in self._iter_iris())) + + def _iter_suffixes(self): + """Iterate over suffixes of the ontology entities in the namespace. + + :return: An iterator over the entity suffixes. + :rtype: Iterator[str] + """ + return (str(iri)[len(str(self._iri)):] for iri in self._iter_iris()) + def __contains__(self, item): """Check whether the given entity is part of the namespace. From a66728cfe7a6eafd8e990d25d9e6bd5ce13045fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Dom=C3=ADnguez?= Date: Tue, 25 May 2021 11:10:16 +0200 Subject: [PATCH 2/3] Unit tests for IPython autocompletion. --- tests/test_namespace.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_namespace.py b/tests/test_namespace.py index 274e6ba4..0524441a 100644 --- a/tests/test_namespace.py +++ b/tests/test_namespace.py @@ -515,6 +515,16 @@ def test_get_entity_name(self): "City_T" ) + def test_autocompletion_ipython(self): + """Checks that all the expected ontology entities are in __dir__. + + The check is done just for the `cuba` namespace. + """ + expected = {'activeRelationship', 'passiveRelationship', + 'relationship', 'attribute', 'path', 'Entity', 'File', + 'Nothing', 'Wrapper'} + self.assertSetEqual(set(cuba.__dir__()) & expected, expected) + if __name__ == "__main__": unittest.main() From 9166ae9c13b84ec10e8648f2f14889bfa6c31dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Dom=C3=ADnguez?= Date: Thu, 27 May 2021 14:25:48 +0200 Subject: [PATCH 3/3] Code review changes. --- osp/core/ontology/namespace.py | 2 +- tests/test_namespace.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osp/core/ontology/namespace.py b/osp/core/ontology/namespace.py index d30033dc..b7eefcc3 100644 --- a/osp/core/ontology/namespace.py +++ b/osp/core/ontology/namespace.py @@ -41,7 +41,7 @@ def __dir__(self): """ entity_autocompletion = self._iter_labels() \ if self._reference_by_label else self._iter_suffixes() - return itertools.chain(super().__dir__(), entity_autocompletion) + return itertools.chain(dir(super()), entity_autocompletion) def __str__(self): """Transform the namespace to a human readable string. diff --git a/tests/test_namespace.py b/tests/test_namespace.py index 0524441a..81efd853 100644 --- a/tests/test_namespace.py +++ b/tests/test_namespace.py @@ -523,7 +523,7 @@ def test_autocompletion_ipython(self): expected = {'activeRelationship', 'passiveRelationship', 'relationship', 'attribute', 'path', 'Entity', 'File', 'Nothing', 'Wrapper'} - self.assertSetEqual(set(cuba.__dir__()) & expected, expected) + self.assertSetEqual(set(dir(cuba)) & expected, expected) if __name__ == "__main__":